Guild icon
swift-developers-japan
開発環境, ライブラリ / uikit
Avatar
こんにちは!好きなプロパティはUIViewの exclusiveTouch です
Avatar
omochimetaru 4/27/2017 3:59 AM
僕は clipsToBounds が好きです。
Avatar
わかる おれもすき
Avatar
omochimetaru 4/27/2017 4:00 AM
Core Graphicsのパワーを感じて好き
Avatar
こんにちは!僕はisUserInteractionEnabledと友達で、よく喧嘩します!
Avatar
最近やっとUINavigationController倒した
Avatar
.alphaが好きです
Avatar
omochimetaru 4/27/2017 4:15 AM
ああ〜 いいですね (edited)
Avatar
アプリ作り始めてから UIKit に殴られ続けてる
Avatar
あるViewControllerから指定したViewControllerまでUINavigationControllerも含めて貫通してdismissしてくれるソリューションとかないですかね
10:39 AM
こんなの書いてるんですけど、捨てたい... /// viewControllerから再帰的に画面遷移でtoViewControllerまで戻る fileprivate func recursivelyDismissViewController( _ viewController: UIViewController, toViewController: UIViewController, completion: @escaping (_ dismissedViewController: UIViewController) -> Void) { guard viewController != toViewController else { completion(viewController) return } guard toViewController != self.rootViewController else { completion(viewController) return } if let presentingViewController = viewController.presentingViewController { viewController.dismiss(animated: false, completion: { [weak self] in self?.recursivelyDismissViewController( presentingViewController, toViewController: toViewController, completion: completion) }) } else if viewController.navigationController?.viewControllers.contains(toViewController) ?? false { viewController.navigationController? ._transition_router_popToViewController( toViewController, animated: false) { completion(toViewController) } } else if let nvc = viewController as? UINavigationController, nvc.viewControllers.contains(toViewController) { nvc._transition_router_popToViewController(toViewController, animated: false) { completion(toViewController) } } else { completion(viewController) } } (edited)
Avatar
最近まさに同じことをやっている・・・
10:40 AM
If you present several view controllers in succession, thus building a stack of presented view controllers, calling this method on a view controller lower in the stack dismisses its immediate child view controller and all view controllers above that child on the stack.
10:40 AM
根本の方をdismissするとその上のやつは全部消える、みたいには書いてありますけど、その挙動だと駄目でした?
Avatar
unwindsegueueっていうのもある
Avatar
全部は消したくないというのがあってですね
Avatar
A -> B -> C -> D -> E みたいに presentが重なってて、 C, D, E を剥がしたいなら、 B.dismissで C,D,Eが消えます
10:42 AM
A -> B -> C -> D -> E において B-> C -> D を消して A->E にしたい、 みたいなのは、iOSだとできない気がする
Avatar
unwindsegueueっていうのもある
Storyboardだとそういう機能もあるんですね、極力使いたくなくて遷移周りは敬遠してました
Avatar
EをDから剥がしてAにつけなおすとかできないんですっけ?
Avatar
できないと思ってる。 UINavigationControllerの中の viewControllers であれば好きにいじくれるけど、UIViewcontroller.present()のスタックは自由が効かない?
Avatar
ふむ
Avatar
そのスタックは基本弄れない
10:46 AM
クソみたいなワークアラウンドがないことはない
Avatar
rootがnavigationControllerなんですが、基本push遷移でpresentで遷移するパターンもあって、あるイベントを受け取ったら指定した遷移履歴に戻るという
10:46 AM
要件自体がひどいって話はあるんですが
Avatar
navigationControllerの中に入ってる横並びのやつらについては入れ替えや部分抜きなどなんでもできますよ
Avatar
NavigationControllerのアニメーションをカスタマイズして
10:47 AM
present/dismissっぽくpush/popすればまあ
10:47 AM
好き放題出来ますね
10:48 AM
とりあえずNavigationBarは消す
Avatar
navigationを横で見て [N1 -> N2] -> A -> B -> [M1 -> M2] みたいに横と縦がいりまじってるときにどこまで、、、みたいなのはループで頑張る感じになりそう
10:48 AM
@tarunon その手があったか
Avatar
@tarunon NavigationBarを捨てたい人生だった
Avatar
すぐ捨てる
10:48 AM
NavigationBarは生かしておいてはいけません
Avatar
カスタマイズ性無さすぎてひどい
Avatar
必ず捨てます
Avatar
どこ行っても頑張ってカスタムする輩がいて辛いです
Avatar
まずこれ捨てないと、NavigationControllerからpresentするViewControllerが、ステータスバー消してたりすると
10:49 AM
アニメーションが破壊される
Avatar
なんかナビゲーションバーを消してると、左端をフリックして戻るやつが死なない?
10:49 AM
あれが死ぬ条件と死なない条件がよくわかっていない
Avatar
んなのdelegate張り替えれば復活するんや
Avatar
なんか正しく動くようにする方法があるのね。
Avatar
navigationController.interactivePopGestureRecognizer?.delegate
10:50 AM
これを奪う
Avatar
え、ヤバそう
Avatar
死ぬ条件は
10:51 AM
NavigationBarを触る、leftButtonItemを触る
10:51 AM
ここいらだったはず
10:51 AM
まあどうでもいいんで復活させてこっちの好きな時にenableフラグいじっておけば
10:51 AM
動くよ
10:51 AM
まーー
10:51 AM
interactivePop、自作するのをおすすめします
10:51 AM
気合で実装しよう
Avatar
気合
Avatar
えーっと、クソみたいなワークアラウンドのほう
10:52 AM
ちょっと検証するんでお待ちを
10:52 AM
最近確認した動きでイケるんじゃないかと踏んでるのがある
Avatar
なんと...ありがたき🙏
Avatar
ダメだった
😫 1
10:58 AM
すみません
Avatar
いえいえ、検証頂きありがとうございます 🙇
Avatar
えーっと
10:59 AM
じゃあクソみたいなワークアラウンドその2を
10:59 AM
UINavigationControllerをカスタマイズして、present/dismissライクに動くpush/popを作ります。
11:00 AM
このRootNavigationControllerはNavigationBarを消しておく
11:00 AM
次、こうすると、オレオレpresentでUINavigationControllerが使えなくなるように思えますが
11:00 AM
UIViewControllerにUINavigationControllerをchildViewControllerとして追加すれば、push可能なんで
11:01 AM
それをオレオレpresentで出せば、UINavigationBarも使えますね (edited)
Avatar
なるほど、デフォルトのpresent/dismiss捨ててしまえばパターン統一できますもんね
Avatar
そこまでやる価値あるのかちゃんと考えたほうが良いとは思います
Avatar
最初から組むならその方式でやりたいお気持ちです
11:05 AM
いや、今もいけるのかな...検討して見ます
Avatar
(やめておいたほうが良いと思う)
Avatar
(やっぱりorz)
Avatar
この手のWorkaround、問題は
11:06 AM
作った当時のメンバーしか理解不能になってしまうことです
11:06 AM
メンテナンス不可能なモノが出来てしまう。
11:06 AM
例えば将来のiOSでpresent/dismiss 或いは push/popのアニメーションが変わったりしたら、その時のメンバーがそれを追いかけることが出来るのか
11:07 AM
そういうことも考慮するべきでしょう
Avatar
なるほど
Avatar
それでもなお僕はまず最初にNavigationBarを消しますけどねw
11:09 AM
こいつは許せん
Avatar
厄介ですよねー...表示/非表示で切り替えてるとフリックで戻る時に挙動が怪しくなる
11:10 AM
UIいじれないのも辛いですが
Avatar
画面遷移のアニメーションがバグレベルで壊れている
Avatar
おかげでこんな処理入れないといけないです enum ViewControllerInteractiveEvent { case popGestureCompleted case pushedOrPoped case cancelled } extension UIViewController { func hoge_receiveInteractiveAction(action: ((ViewControllerInteractiveEvent) -> Void)?) { if let coordinator = self.transitionCoordinator, coordinator.initiallyInteractive { coordinator.notifyWhenInteractionEnds({ context in if context.isCancelled { action?(.cancelled) } else { action?(.popGestureCompleted) } }) } else { action?(.pushedOrPoped) } } } (edited)
Avatar
質問なんですが、これ、画面遷移挟んでステータスバー切り替えるの
11:14 AM
ちゃんと動きます?
11:14 AM
ステータスバー切り替えたの、修正する方法はついぞ見つけられなかった。
Avatar
あー...どうなんでしょう、試しておらず
Avatar
UINavigationControllerにWebView追加して、Youtube再生すると壊れたアニメーション確認出来ます。
11:16 AM
超簡単に壊れる
Avatar
omochimetaru 5/12/2017 3:44 AM
iOS10LongAlert
3:44 AM
iOS10でくっそ長い文言をUIAlertControllerに渡すとボタンが隠れる(本当は button1, button2, cancel の3つがある)
3:44 AM
たすけてー
3:46 AM
@IBAction func onButton() { var message = "" for _ in 0..<1000 { message += "長い文言" } let alertController = UIAlertController(title: "aaa", message: message, preferredStyle: .alert) alertController.addAction(UIAlertAction(title: "button1", style: .default) { print($0) }) alertController.addAction(UIAlertAction(title: "button2", style: .default) { print($0) }) alertController.addAction(UIAlertAction(title: "cancel", style: .cancel) { print($0) }) present(alertController, animated: true, completion: nil) }
3:46 AM
再現コード・・・
Avatar
omochimetaru 5/12/2017 4:44 AM
うおおおお
4:44 AM
ボタンのところもスクロールできたwwwwww
😱 1
Avatar
まずもってこんなのを渡すのはどうなんだw
Avatar
omochimetaru 5/12/2017 4:45 AM
それはね、言われると思ったけど、今はするーしてほしいんだ
4:47 AM
iOS9まではボタンの部分はスクロールしなかったけど、iOS10で変わったってことは
4:47 AM
ボタンが100個とかあるときに
4:47 AM
メッセージ部分が狭くなってしまう仕様を改善するために
4:47 AM
ボタンが増えてもボタン領域が拡大しないように
4:48 AM
仕様変更されたのかな
Avatar
Alertにも長文を求められる時代w
6:16 AM
iOS8, 9でも動作させたいならapplicationFrame渡すと良いらしいです
Avatar
omochimetaru 5/12/2017 6:16 AM
iOS8, 9では
6:16 AM
正しくテキスト領域が小さくなって
6:16 AM
ボタンが全部見えるんですよね
6:17 AM
iOS10では、ボタン達が一つのスクロール領域に押し込められて、スクロールすると見えるようになる。
6:17 AM
iOS9でも10でも、テキスト領域自体はちゃんとスクロールになる。
Avatar
なるほど 👀
Avatar
iOS11対応やってるのですが、10-11 間のAPIの変更ってどこで見つけられますかね。
7:27 AM
7:27 AM
これかと思ったけど、select versionにそれっぽいの見当たらない
🤔 1
7:28 AM
7:28 AM
いつものここにも無いっぽい
7:30 AM
あ、10.0だ
Avatar
そういったやつが欲しいわけです
7:31 AM
see OS X v10.11 API Diffs
コレジャナイ感 https://developer.apple.com/search/?q=iOS%2011%20API%20diffs
7:32 AM
公式じゃないか。
7:32 AM
旧バージョンのタイトルにならって iOS 10.3 to iOS 11.0 API Differences で検索してみたらそれっぽいのが。↑
Avatar
なるほ
7:33 AM
I/Fの比較だけして機械的に出してるのかな?
7:35 AM
iOS Release Notes is sometimes updated after a release is distributed. You can check for the most up-to-date version of iOS Release Notes at the Apple Developer website by checking http://developer.apple.com/go/?id=ios-sdk-release-notes.
🤔
7:39 AM
iPhone X以外でのNavigationBar周りの動作の違いはどこみると良いのかな
7:41 AM
ドキュメント見つからないけど、もともと調べ始めた原因はみんな困っているっぽいやつでした > https://stackoverflow.com/questions/44932084/ios-11-navigationitem-titleview-width-not-set (edited)
Seeing a behavior on iOS11 with a navigationItem.titleView where the width of the titleView is not the full width of the screen. I have a custom view that I set as the titleView. Previous to iOS11...
Avatar
UISearchControllerで壊れる奴ならまさにこの前治したんですがそれかしら
Avatar
UISearchController使ってなくてnavigationItem.titleViewにsearchBarを直で突っ込む実装ですね
8:03 AM
↑↑のページ通りにしたら治りました
Avatar
iOS10までは、frame.size.width伸ばしてから titleViewに突っ込めばそれを最大値としていい感じになってた。
8:08 AM
それが intrinsicContentSize(だけ?)を見るようになったですね。 (edited)
Avatar
なるほど
Avatar
iPhoneXで、UIViewController#hidesBottomBarWhenPushedをtrueにした状態のVCをpush遷移すると、タブバーの位置がズレる。
9:58 AM
Contribute to iPhoneXTabBar development by creating an account on GitHub.
10:00 AM
Avatar
オッ
10:01 AM
これは僕が治せるやつな気がしますね
Avatar
はよ
Avatar
おっ
Avatar
はよなおして
Avatar
10:01 AM
ちょっとまってや
Avatar
邪悪じゃないやり方がいいです
Avatar
邪悪の定義について
😈 3
10:05 AM
Discordってムービーそのまま挙げれるっけ
Avatar
今日あげれたよ 添付ファイルになるけど
10:06 AM
ほい
10:06 AM
こういう動きのやつは作った
10:07 AM
でも要件hidesBottomBarWhenPushedだからちょっと違うな~
Avatar
動きたくないです
Avatar
なんかよさげにヌルヌルしている
Avatar
ヌルヌルだけどhidesBottomBarWhenPushedとはちょっと違うっぽい
Avatar
オレオレだからね👿 (edited)
Avatar
これってtabBarのframeをviewWillDisappearとかで弄ってるんですか? (edited)
Avatar
tabBarController.tabBar.isHidden = true tabBarController.additionalSafeAreaInsets.bottom += 1.0 tabBarController.additionalSafeAreaInsets.bottom -= 1.0 tabBarController.view.layoutIfNeeded() これやると、SafeAreaが再計算されます (edited)
Avatar
self.additionalSafeAreaInsets.bottom += 1.0 self.additionalSafeAreaInsets.bottom -= 1.0 ww
Avatar
additionalSafeAreaImstesを変更してview.layoutIfNeededすると、強制的にsafeAreaの再計算が走るっぽい
10:11 AM
同じ値はチェックされてるっぽくてダメだった
Avatar
なるほど
Avatar
@tarunon こんなんどうやって見つけるの 頭おかしい(褒)
Avatar
偶然見つけた
Avatar
頭おかしい
Avatar
豪運
Avatar
その運なんなん
10:12 AM
来世は絶対初手地獄に落ちてほしい
Avatar
@Yuta Saito 今試したんですが別にレイアウト崩壊しないですね
10:13 AM
普通に普通の方法でやって、レイアウト崩壊しない。
Avatar
んん
Avatar
PushしてるViewControllerの条件が何か他にある?
Avatar
Contribute to iPhoneXTabBar development by creating an account on GitHub.
Avatar
粉砕された
💩 1
10:17 AM
お、あれ??
10:17 AM
俺のTabBarControllerだと普通のやり方でも崩壊しないけど、普通のTabBarControllerは崩壊しますね
10:17 AM
あらー
Avatar
>俺のTabBarController 何してるのか気になる
Avatar
もうTaruKitとして公開してくれ
Avatar
viewWillLayoutSubviewsでTabBarのorigin調整してました。
10:18 AM
リポジトリ公開するけん、ちょっとまって
Avatar
これってsafeArea壊れませんか??
Avatar
僕のやつはSafeAreaちゃんとやってるんで大丈夫です
10:22 AM
XWorkarounds - Workaround for iPhoneX/iOS11
10:22 AM
レドメ無いけどコード読めばわかると思います
10:24 AM
XWorkarounds - Workaround for iPhoneX/iOS11
Avatar
治りました
👍 1
Avatar
UIKitもういやや
😂 1
Avatar
これ明確なiOS11のバグですよね?
Avatar
そうだと思います
Avatar
辛い💧
10:30 AM
^ 同様の報告がありました。重複して報告しておくといいですよ。
10:31 AM
^のレポートは発売前だからSimulatorって書いてあるけどデバイスでも起こる。
👻 4
Avatar
LINEのチャット画面への遷移とかこれで死にそう
Avatar
わかった、iOS11.2でUINavigationControllerをchildViewControllerにしてtopAnchorを設定すると無視されます
8:37 AM
矛盾したconstraint扱いになって無かったことになる (edited)
8:42 AM
↑1個間にView突っ込んでそっちをAutolayout、ChildViewController.viewはautoresizingMask = [.flexibleHeight, .flexibleWidth]にして自己解決しました。やったぜ
👏 1
Avatar
やはりURLSessionってメモリ管理おかしくないですか?
🤔 3
1:33 AM
まったく同じコードを動かしても Instrumentsがメモリリークを検出するとき,しないときがある・・・・
Avatar
理由判明.
10:06 PM
この挙動の問題は,既知の問題である「プロキシを使っているとURLSessionがメモリリークを起こす」という問題に起因していることが判明.
10:08 PM
https://forums.developer.apple.com/thread/71479 URL1があったとき URL1をプロキシありで,URLSessionで一度ダウンロード→メモリリーク そのあと,プロキシなしで,URLSessionでもう一度,URL1をダウンロードすると,プロキシなしでもメモリリークする. このとき,URL2を,同時にプロキシなしでURLSessionで新しくダウンロードすると,メモリリークしない. というわけで,プロキシ越しでURLSession使う場合は,メモリリークが自分のバグなのか,Appleのバグなのか,注意した方が良さげ. そもそも,Instrumentsでも,メモリリークの箇所は,CoreNetworkの方が原因って出てくるから,それはそうなんだが・・・・・・・. 以上,報告でした. (edited)
👀 5
Avatar
Yoshikuni Kato 12/22/2017 6:19 AM
UINavigationControllerviewControllers(もしくはtopViewController or visibleViewController)の変化をKVO(UINavigationControllerDelegate以外)で検出したいと思っているのですが、可能かどうかご存じの方いらっしゃいますでしょうか? 以下のコードで試したのですが、push / popしても何も反応ありませんでした。 class CustomNavigationController: UINavigationController { var token: NSKeyValueObservation? override func viewDidLoad() { super.viewDidLoad() token = self.observe(\.viewControllers) { observed, change in print(observed) print(change) } } } 根源的にやりたいことは次のようなものです: status barのappearanceの変化のために、childViewControllerForStatusBarHiddenをoverrideし、topViewControllerを返すようにしています。 class CustomNavigationController: UINavigationController { override var childViewControllerForStatusBarHidden: UIViewController? { return self.topViewController } } このメソッドのドキュメントを見ると、 If you change the return value from this method, call the setNeedsStatusBarAppearanceUpdate() method. とあり、topViewControllerが変わった段階で setNeedsStatusBarAppearanceUpdateをcallする必要があるので、変化を検出したいです。 (edited)
Avatar
KVOでは無理なので、毎回DelegateとOverride駆使して辛い感じになる印象です。
Avatar
Yoshikuni Kato 12/22/2017 6:33 AM
やはりそうですか・・・。手動で管理するしかないっていうことなんですかね。ありがとうございます。 ちなみにですが、KVOで検出できないっていうことは、内部的には普通の配列ではなくて何か別の構造で保持しているということなんでしょうか (edited)
Avatar
Kishikawa Katsumi 12/22/2017 6:36 AM
"UINavigationControllerDidShowViewControllerNotification" という通知を監視すると要求は満たせると思います。問題はUndocumentedなことですけど。
👀 3
6:38 AM
もし通知の名前が変わったり意図したタイミングで来なくなったらわかるようにテストを置いておけばいいんじゃないかという気もします。
Avatar
Yoshikuni Kato 12/22/2017 6:41 AM
なるほど・・・ありがとうございます! プロダクションで使っても大丈夫なのでしょうか・・・?(ただのStringへのaliasだから大丈夫ってことですかね・・・?)
Avatar
Kishikawa Katsumi 12/22/2017 6:50 AM
大丈夫かどうかは私には何とも言えないですけど、今回の場合のようなことのためにUINavigationControllerをサブクラスを作るのは私も面倒だと思うので簡単に済むならこっちの方で済ますかと思います。
Avatar
Yoshikuni Kato 12/22/2017 6:58 AM
参考にさせていただきます。ありがとうございます〜
Avatar
ちなみに取得するのはpush/popだけで大丈夫ですか? present/dismiss、ひいてはUIPageViewControllerのスワイプも同様に取りたかったりしませんか?
Avatar
Yoshikuni Kato 1/5/2018 4:34 AM
いまのところ、present/dismissとかUIPageViewControllerとかは使用箇所が少ないので個別に対応している感じです。
Avatar
何年前の話やと言われそうですが,Storyboardをデバイスで分けるのってXcode上でできなくなった・・・? こんな感じで
3:20 PM
あ,できた
Avatar
Plain Style unsupported in a Navigation Item warningについて質問です IB上でUIBarButtonItemのstyleをPlainにすると警告が表示されてしまいますが、これはどう対処すべきでしょうか。 ドキュメントを参照すると、 https://developer.apple.com/documentation/uikit/uibarbuttonitemstyle
case plain Glows when tapped. The default item style.
case bordered A simple button style with a border. [Deprecated]
case done The style for a done button—for example, a button that completes some task and returns to the previous view.
とあり、たしかにplainもborderdもダメならdoneしかないとはいえ、説明からするとdoneも不適切に見えます。 https://qiita.com/takashings/items/ca3558d9ee94e4ecd5fb この記事には
iOS7以降ではデザインが刷新されて、「UBarButtonItemStyleDone」一択になりました。
とありますが、ソースがありません。 このソースがあれば安心してdoneに変更できるのですが…
storyboardでいろいろとパーツを配置していると、このWarningが出るようになりました。
Avatar
私もソース探してみたんですが、たしかにないですね・・🤔
Avatar
Appleにfeedback送っておきました。返事あるかなー
👍 2
Avatar
omochimetaru 2/27/2018 3:58 AM
SafeAreaのXIB周りの作りはかなり良い感じがする
3:59 AM
iOS7でTop/BottomLayoutGuideが出た時はいろいろあって渋い気持ちになったけど
Avatar
それな
3:59 AM
iPhoneXに限って言うと、Statusbar周りの壊れもなくなった。大分平和になったと思う。
Avatar
omochimetaru 2/27/2018 3:59 AM
[ ] SafeLayoutGuideのチェックボックスでビューごとに有効無効して、constraintはるときに選択肢出したり消したりできるのとか、これだよこれ、って感じ (edited)
Avatar
Kishikawa Katsumi 2/27/2018 4:00 AM
ビューごとにON/OFFできるのが柔軟でいいですね。
😀 1
Avatar
omochimetaru 2/28/2018 2:21 AM
Cartography - A declarative Auto Layout DSL for Swift 📱📐
2:21 AM
めちゃくちゃいい
Avatar
#beginner-help-archived で話してた |[A]-(>=0@1000)-[B]| |[A]-(>=0@1000)-[C]| |[A]-(0@750)-|A.right = min(B.left, C.left) とかで表現したいっていう話ですが、 [A]-(>=0@1000,0@750)-[B] [A]-(>=0@1000,0@750)-[C] でも同じ事実現できるので、それなら min 実装できそうだと思った次第。
👀 1
Avatar
↑これちゃんと動くんですか
3:16 AM
ああ
3:16 AM
それはボクが提案してたほうほうで内部的に使ってた奴 (edited)
Avatar
omochimetaru 2/28/2018 3:16 AM
Cartographyにmin足すのはできそうですね
3:17 AM
演算子でAST組んでるので
Avatar
== か。
Avatar
UIAlertAction のクロージャはメインスレッド以外で実行される場合があるのでしょうか? UIAlertAction のクロージャの中で UI を触る場合は必ず DispachQueue.main.async などで囲みますか? (edited)
Avatar
Kishikawa Katsumi 3/15/2018 2:59 AM
@kuma2120 ないと思いますよ。実際にそういう挙動が観測されない限りはクロージャの中でメインスレッドにディスパッチしたりは普通はしません。 (edited)
3:01 AM
いくつかのシステムが勝手に出す類のアラートビューはその限りではないです。パーミッションを取得するものとか。
Avatar
昔DispatchQueue.main.asyncの中でUIWebViewのJavaScriptを叩いてAlertを表示すると消えなくなる事象がありましたね。
3:11 AM
あれはもう治ったのかな
Avatar
ありがとうございます!!ここ曖昧なまま実装してしまっていました
Avatar
UIToolbarとか,UINavigatoinbarのすりガラス効果ってどうやってオフにするんでしたっけ? (edited)
Avatar
えーと isTranslucent = false だったかな と思ったけどこれiOS 3からある。じゃあ違うかも。 (edited)
2:29 AM
↑いや、やっぱり isTransclucent をfalseにするので合ってそうです。
Avatar
やってみます
Avatar
でも、これfalseにすると真っ白になっちゃった。。。
Avatar
うーむ,難しい 自前でtintColorをセットする必要性がありそうですね・・・・面倒臭いw
Avatar
そもそも自分で barTintColor を設定するだけで、その色のアルファ値をかなり下げない限りはすりガラス効果がなくなるみたいですね。 気にしたことなかった。 https://qiita.com/yimajo/items/4781d5d2712e34677db2 (edited)
iOS7からのUINavigationBarの自動半透明がiOS7.0.3からオフになっているようです。 追記: iOS7.0.4にしてみましたが半透明じゃないままですね。

Facebookアプリで違いを見る

Faceb...
Avatar
tintColorのalphaで調節みたいですね・・・・情報ありがとうございます
Avatar
UITableViewでsectionの数を増やすと
6:39 AM
スクロールがカクツクときがあるなぁ・・・・なんじゃこれ
6:39 AM
section使うのやめるかぁ
Avatar
うーん,やっぱりsectionなくして,全部真っ平らなrowだけにしたら,カクツキがなくなった
Avatar
TableViewCellの中の要素をStackViewで組み、isHiddenを操作してトルツメしていたら、トルツメは正常にされるがviewが表示されたままになってしまう(レイアウトは意図した通りになるがviewが見えてしまう感じ)ことが多々あって、isHiddenだけでなくalphaもいじってviewを不可視にするというコードを仕方なく書いてるんですが
👮 1
8:09 AM
この辺りの対策方法ご存知の方いますか?そもそもUITableViewCellの中の要素をStackViewで管理するのがよくないんですかね、、、 (edited)
Avatar
stackviewのisHiddenが壊れてるみたいな話、 @Yuta Saito もしてたな
Avatar
一番上から順番に、 1. それはどうしてもTableViewが必要ですか 2. TableViewCellはhiddenで切り替えるより別のクラスにして管理した方がいいですよ 3. StackViewのhiddenはStackViewがネストした時にも問題があったりするので一番底のviewでlayoutし直さないといけないケースが有りました。
Avatar
Kishikawa Katsumi 3/22/2018 8:15 AM
@kichikuchi 再現できるプロジェクトを共有できませんか?
Avatar
1. 質問一覧をページングで表示する、みたいな画面なのでTableViewは使わざるをえなそうです😢 が、安易に使わないよう意識していきます! 2. 一つのセルを使いまわすのではなくて、各種レイアウトで組んだcellを用意して出し分けたほうがいいという意であってますかね? 3. 1番底のViewでlayoutし直す、がどういうことなのかいまいち把握できなかったんですが、例えば今回の自分のケースでは下記のようなよくある感じのコードでcellの更新をしているんですが、一番底のviewでlayoutし直すというのは何を意識したらいいんでしょうか? // Cell, ざっくりとですが下のような構造をしてます ContentView |- label |- StackView |- categoryLabel |- View |- StackView class Cell: UITableViewCell { // cellForRowで呼ばれる func configure(_ item: Item) { categoryLabel.isHidden = item.category.isEmpty } }
8:30 AM
@Kishikawa Katsumi すみません!会社のコードしかないためおみせできるものが手元にないです😢
Avatar
Kishikawa Katsumi 3/22/2018 8:35 AM
@tarunon UITableViewを避けるべきというところ
8:35 AM
同意できないんですけど、UITableViewを使わない方が良い例ってそんなにありますか?
8:36 AM
一覧で表現するデータは素直にUITableViewを使った方が良いと思います。
8:39 AM
件数が有限の場合も、それこそ有限ならどう実装しても大して複雑にならないのでUITableViewで良いと思います。
Avatar
2. ですです。状態に応じて表示するCellを変更して、それぞれのCellは高さ固定になってるイメージです。
9:10 AM
@Kishikawa Katsumi TableViewのしんどい点、いっぱいあるんでまとめます。ここ間違ってるよ、みたいなのがあれば教えて頂けるとありがたいです。ちょっと時間いただきますね。 (edited)
👀 5
Avatar
Kishikawa Katsumi 3/22/2018 9:12 AM
@tarunon ありがとうございます。お手すきのときに 🙇🏻 私も改めて勉強しておきます。
🙇 1
9:14 AM
2については同意です。もちろんケースバイケースで、状態を切り替えた方がシンプルに書ける場合もありますが、それでがんばれる範囲はそんなに大きくないので、早晩、複数のセルを使い分ける方がスッキリすることが多いです。 (edited)
Avatar
皆さんありがとうございます〜🙏 ! 一つのセル使いまわさないでなるべく複数セル使い分ける方針で書き直したいと思います!
Avatar
omochimetaru 3/22/2018 9:29 AM
@kichikuchi setNeedsLayout()とかsetNeedsDisplay()とかは駄目でした?
Avatar
あ〜、試してないです!
9:32 AM
isHiddenと合わせてalphaいじるの辛すぎるので
9:32 AM
そちら試してみます!
Avatar
omochimetaru 3/22/2018 9:33 AM
isHiddenを書き換えた直後にとりあえずcellとかstackViewに対して呼んでみると良いかも・・・
Avatar
stackViewに呼べばワンチャンあるかも
9:34 AM
3はネストしたstackViewの一番親に対して、setNeedsLayout, layoutIfNeedを読んで解決した記憶があります
👏 1
Avatar
stackViewのサブビューにisHidden=trueを2回入れると2回isHidden=falseしないと表示されないみたいなバグを最近踏んだんですけどそれとは関係ない?
Avatar
omochimetaru 3/22/2018 9:37 AM
そのバグ意味不明で笑う
Avatar
ワロタなんだそれはw
Avatar
僕のは表示したくないのに出ちゃうケースですが、もしかしたら関係あるかもですねw
Avatar
setNeedsLayout, layoutIfNeed, setNeedsDisplayあたりをstackViewに呼んでもやはりレイアウト崩れちゃいました、、、😢
😭 1
Avatar
だめか〜 残念。
Avatar
stackViewを置いて一つのcellでレイアウトいじるっていうのがバッドパターンぽいので、cell分ける方針に切り替えます! みなさん助言ありがとうございました🙏
Avatar
Kishikawa Katsumi 3/22/2018 10:56 AM
@kichikuchi 念のためなんですけど、すべてメインスレッドで呼ばれてますよね?
Avatar
はい。 viewの操作はクロージャなどでは行っておらず、 func configure() の最下部で print(Thread.isMainThread) して trueを吐いてるので全てメインスレッドで呼ばれてると思います。 (edited)
Avatar
@kichikuchi あまり良い対応ではないかもしれませんが、stackviewを貼り付けているcellでcell.clipsToBounds = trueてやると、viewが消えませんか? (edited)
Avatar
ありがとうございます。ちょっと試してみます!
Avatar
Kishikawa Katsumi 3/23/2018 5:59 PM
https://twitter.com/AdityaRajveer/status/931427933264023552 同じ問題にあった人もいるみたいですね。 Hiding and showing views in a stack view is cumulative. のような感じでバグレポートしたらいいかな。
@Tricertops It actually is funny. Even though showing after hiding is cumulative but hiding after showing isn’t. 😛 https://t.co/Z0S0TbyVNK
👀 2
Avatar
TableViewのあれこれまとめました。思いつく範囲で書いています。 cc @Kishikawa Katsumi https://gist.github.com/tarunon/de72868fd5cb48965019d45df7775721
👀 1
Avatar
Kishikawa Katsumi 3/25/2018 6:41 AM
@tarunon ありがとうございます。一つ一つの不満は納得できるのですが、ちょっと想定と異なるというか、ここからTableViewを使わない方が良いとなるにはだいぶギャップがあるように思います。私はTableViewのAPIは気をつける必要があるよね、というくらいの印象なので。 Table/CollectionViewを使わない場合はどういう作るのですか?
Avatar
例えば一部だけTableViewの標準と似た見た目があるのであれば、そういう見た目のViewを作って再利用するのが良いと考えています
6:43 AM
Viewを作るコストの方が、TableViewのあれやこれやで腐心するコストより安いのではないか、というアイディアです
6:46 AM
あと、「気をつけないといけないよね」で、人間が気をつけるかというと結構僕はそこは懐疑的で、やっぱり人間なんで間違えるんですよ、なのでできるだけ簡単で気をつけなくて良いAPIの方が良いんじゃないかなぁと。
Avatar
Kishikawa Katsumi 3/25/2018 6:49 AM
「気をつけないといけないよね」で、人間が気をつけるかというと結構僕はそこは懐疑的で、やっぱり人間なんで間違えるんですよ、なのでできるだけ簡単で気をつけなくて良いAPIの方が良いんじゃないかなぁと。
それは同意。なんですけどTableViewのAPIはそうなってるのはなるべくしてなってるので、もっと簡単なAPIのTableViewが作れるかというと難しいと思いますね。 TableViewは使いつつできることを限定して簡単なAPIにラップするという方が、良いんじゃないですか?
(edited)
Avatar
Discordに引用のマークダウンは無いです。かなしい。 (edited)
Avatar
Kishikawa Katsumi 3/25/2018 6:51 AM
ないのか。。。tarunonさんのオレンジの部分はどうやって書いたのですか?
Avatar
それ前僕も勘違いしてたんですが、自分宛てのリプライはオレンジ色になりますw
Avatar
Kishikawa Katsumi 3/25/2018 6:52 AM
あ、そういうことか。。リプライのハイライトでしたか。😅
Avatar
TableViewのAPIは、Reuseのためにかなりゴテゴテになっている印象が強くて、Reuseによる恩恵を享受しないのであれば、素のViewで必要十分だったのでは?というのが最近の僕の認識です。TableViewをラップする、とはいっても結局Cellへのアクセスを考えると難しいし、そのうち「こういう機能がほしいんだよね!!!」って言われてぐにゃぁってなるのは想像に難くないし…
Avatar
Kishikawa Katsumi 3/25/2018 6:57 AM
8、9割同意なんですけど結論は異なりますね😆パフォーマンスの問題がない(=Reuseによる恩恵を享受しない)ときはStaticCellで作るか、StaticCellを使わなくても同様に1行1セルのように実装した方がいいと思います。
6:58 AM
スクロールやセルを選択するような要素がない、だったら別のViewでもいいですけど、そういうのがあるならTableViewを使った方がいいと思います。 (edited)
6:59 AM
セルの選択とスクロールの組み合わせを標準と同じように実装するのは大変だし不具合を起こしやすくないですか?
Avatar
ハイライトをpopのタイミングで消す、とかスクロールはscrollToIndexPathの実装でしょうか?
Avatar
Kishikawa Katsumi 3/25/2018 7:03 AM
私が今頭に思い浮かべていたスクロールとセルの難しい問題は、セルをタップして触れたままスクロールするとハイライトがキャンセルになるとか、スクロール中(画面が動いてる間)にタップして止めても選択にならないとかそういう使い勝手の細かい制御の部分です。
Avatar
なるほど
7:03 AM
スクロール中(画面が動いてる間)にタップして止めても選択にならないとかそういう使い勝手の細かい制御の部分です。
これGoogleがちゃんと実装してなくて
Avatar
Kishikawa Katsumi 3/25/2018 7:04 AM
Gmailですね。
Avatar
GoogleのWeb検索使うと毎回怒りがこみ上げてくる
7:04 AM
なんか到るところこうなってますよw
Avatar
Kishikawa Katsumi 3/25/2018 7:04 AM
それは100%同意です😂
7:06 AM
インタラクティブな要素がないならいいかな。ただ私はインタラクティブな要素がないなら結局どうやっても簡単なので見た目がTableViewならTableView使ったら、と思いますけど。
Avatar
ところでスクロール中にタップして止めても…はUIScrollViewが結構なんとかしてくれてるイメージなんですが
Avatar
Kishikawa Katsumi 3/25/2018 7:09 AM
確認する必要があるけど、合ってると思います。ただ、アクションに反応してる状態で動かすとかは色々書かないといけないはず。
Avatar
ハイライトは、そうですね、そもそもUIButtonで作るとTouchDownのあとはScrollできなくなっちゃったりするんで、それなりに考えておかないといけない。
Avatar
Kishikawa Katsumi 3/25/2018 7:16 AM
他にも編集(挿入削除、並び替え)や標準のコピー&ペーストとかドラッグ&ドロップなどUITable/CollectionViewが標準のUIを提供してるものは多くて、途中からUITableViewにした方が良いとなる可能性もあると思うんですけど、それは起こらないということを最初から判断することは難しくないでしょうか。
7:17 AM
自分で作っていたViewから切り替えるコストはだいぶ高いと思います。
Avatar
TableViewからViewに載せ替えるときにコストが高くつくのがロジック側で、View側はまだなんとかなる、実際にこの間やったからわかることなんですが
Avatar
Kishikawa Katsumi 3/25/2018 7:18 AM
なるほど。
Avatar
ViewからTableViewに変換するのは、UITableViewCellと全く同じ構造のものをUITableViewCellに載せ替えるのはちょっと大変、それ以外はCellでWrapすればなんとかなるケースは結構ありそう、というイメージです
7:19 AM
ロジックは同期アクセス前提で組んでいそうなので、Reuseなものに載せ替えるのは、気をつけてないとかなり大変なことにはなりそう。
7:20 AM
どちらにしてもロジックの載せ替えが肝要になってきますね
Avatar
Kishikawa Katsumi 3/25/2018 7:39 AM
Aの下にB、というような相対的な配置ではなく絶対座標による指定。ViewOnlyでレイアウトを組むことができず、indexPathを設定するためのロジックが必須になる
^ このとき想定しているのはある程度タテに長いけど繰り返し要素などはない、という画面を何で作るかだと思うのですが、これはTableViewを使うメリットは見た目くらいかと思います。使わない選択は全然アリ。
(edited)
Avatar
ですです、僕の想定しているのはまさにそこで
7:40 AM
配列ではないものを、TableViewでやるのはどうなの?ってところです。
7:42 AM
配列、特にページネーションなどを含んだ無限配列なんかは、逆にTableView以外でやろうとするのは難しいので見た目がCellじゃなくてもTableView/CollectionViewでやるべきと思っています (edited)
Avatar
Kishikawa Katsumi 3/25/2018 8:01 AM
同意できます。
安全なアクセスは生成時に限定されている、ReuseもあるのでデータをCellで保持することが出来ない。
これはなるべくしてなってるところなので、Reuseしなくてもパフォーマンスが問題にならなければ、、、なんですけど、このあたりの問題の解決はTableViewを捨てなくても1方向のデータフローやImmutableで解決できないでしょうか?(そっちの方が良くない?)
(edited)
Avatar
それはその通り、、なんですが、、、
8:02 AM
「止事無き事情」がそこかしこに溢れていて、仕方ないなぁという印象があります
👌🏻 1
8:05 AM
止事無き事情と向き合いつつ、綺麗にメンテナンスフルのTableView書ける人がいたらその人はスーパーマンだなぁという感じ
8:05 AM
人類が全部スーパーマンなら、使っていけるんだと思います (edited)
Avatar
Kishikawa Katsumi 3/25/2018 8:08 AM
^ そこは私はデータフローとビューの更新の自由を制限することで大丈夫じゃないか、という考えですね。TableViewを使いつつ外側で解決できるのではと。
8:11 AM
高さがCellの外にある。Self-sizingで楽にはなったが、
高さについてはほとんどの場合Self-sizingを使うよりモデル側で計算した方が良いと考えていますね。Self-sizingが機能するということはもちろん事前に計算するためのデータは揃っているので。
Avatar
文字入力で改行可能な項目が一つあると途端に崩壊しませんか
Avatar
Kishikawa Katsumi 3/25/2018 8:15 AM
正確にやるためには格段に必要な知識は増えます。崩壊はしないと思います。Self-sizingならシステムに任せてうまくいきます?
Avatar
Cellが画面内にあるときの高さ変更はだいたい上手くいかないので、beginUpdate/endUpdateを呼んだり、そもそもupdateRowAtIndexPath(だったかな?)を呼ぶのが正解とかそんな漢字
8:18 AM
そうすると、Cellの内側で起こった変更をどうしてもVC側にハンドルさせる必要が出てきて、ウーンという感じになってきます
Avatar
Kishikawa Katsumi 3/25/2018 8:19 AM
あ、問題を理解しました。それは難しいですね。
Avatar
まあそもそもCellの内部でデータ編集して~みたいなことになってる時点で、Immutableでもなんでもないしなぁ。
8:20 AM
この間の @kichikuchi さんの例にしても、TableViewのCellの中でTextViewで編集やってるように感じられたんですよね。なのでそれは難しいなぁと。
8:21 AM
あ、それは話が混じってる、失礼しました (edited)
Avatar
Kishikawa Katsumi 3/25/2018 8:24 AM
今議論している問題はTableViewの設計に起因するものですね。ビューで自身の高さが変わるイベントが起こった場合はそれをモデルに伝えてTableViewの更新を発火させて(update〜)、TableViewからセルを更新してビューを更新なので、TableVewでやる必要があるなら私はそう作るけど、できるなら避けたいというのは同意します。 よくあるのは入力だけ別コンポーネントで、のような感じですけど。
Avatar
如何せんやっぱり難しいので、使えるんじゃ!使うしかないんじゃ!っていうのを胸を張って言ってもらえると安心できるなという感じなのです😌
Avatar
Kishikawa Katsumi 3/25/2018 8:36 AM
だいぶ理解できました。良かったです。😁
Avatar
@sutokuro 遅レスになってしまいましたが、clipsToBounds試してみましたがダメでした😢
🙇 1
Avatar
高さ50くらいの横スクロールCollectionViewのタップ可能領域を拡げようとしています。今は試しにタップ可能領域を可視化するために、UIViewのなかにCollectionViewをおいて、下記のようにhitTestを使って拡げているんですが、UIView上でスクロールはできるんですが、UIViewをタップしてもCellに対するタップになりません。何かご存じの方いませんか? class CollectionContainerView: UIView { @IBOutlet weak var collectionView: UICollectionView! override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? { guard self.bounds.contains(point) else { return super.hitTest(point, with: event) } let updatedPoint = CGPoint(x: point.x, y: collectionView.frame.origin.y + collectionView.frame.height / 2) return super.hitTest(updatedPoint, with: event) } }
3:04 AM
こちらにサンプルコード置きました。こちらも私が言っていることの補足になれば幸いです。 https://github.com/SeiyaMogami/ExpandedCollectionViewSample
Contribute to ExpandedCollectionViewSample development by creating an account on GitHub.
Avatar
Kishikawa Katsumi 3/28/2018 7:54 AM
Cellの選択はCellじゃなくてUICollectionViewが管理しているので難しいと思います。タッチイベントを自分で処理してUICollectionViewのselectItem~メソッドを自分で呼ぶか、hitTestを使うのではなくて、UICollectionView自体を大きくして見た目をごまかす、などの方法が考えられます。
Avatar
ご回答ありがとうございます🙇 難しいんですね、、、hitTestで座標上書きしちゃえばよしなにできると思っていました。代替案ありがとうございます、検討します!
Avatar
UIPageViewControllerについて質問です。 UIPageViewControllerに生えているviewControllersプロパティは常に先頭が現在表示しているVCという認識であっていますか? 公式サンプルにはそれを前提としたようなコードがあるのですが、ドキュメントを見た限りではそのような記述はありません。。。 https://developer.apple.com/documentation/uikit/uipageviewcontroller/1614106-viewcontrollers https://developer.apple.com/library/content/samplecode/ZoomingPDFViewer/Introduction/Intro.html サンプルにあったコード↓ let currentViewController = pageViewController.viewControllers![0] as UIViewController (edited)
Multi-page PDF viewing with two-page spline in landscape orientation, and single-page zooming in portrait.
Avatar
他のサンプルも1ViewControllerだけ入れてた。ほぉーん。 https://developer.apple.com/search/?q=UIPageViewController&type=Sample%20Code (edited)
Search - Developer
Avatar
2つ以上のvcをsetViewControllersで入れるとクラッシュするんですよね
6:45 AM
前後のvcをキャッシュしているはずなのでviewControllersには複数のvcが入りうると思っているんですけど、その先頭が必ず表示中のvcである、という確証が得られないので困っています。
Avatar
Xcodeから見たsetViewControllersメソッドの説明 // For transition style 'UIPageViewControllerTransitionStylePageCurl', if 'doubleSided' is 'YES' and the spine location is not 'UIPageViewControllerSpineLocationMid', two view controllers must be included, as the latter view controller is used as the back.
🙏 1
Avatar
doubleSidedモードなるものがあるんですね
Avatar
transition styleによって2つViewController入れなきゃいけない時もあると…普段使わないから自分もそんなモードしらなかった
Avatar
そんなモードあるんですね
Avatar
Kishikawa Katsumi 3/29/2018 6:54 AM
ページをめくる途中で裏側が見えるようにしたい、ってやつかな。
Avatar
あーなるほど、doubleSidedだ
Avatar
そういう目的か
Avatar
UIPageViewControllerのアトリビュートの設定についてサンプルを用いながら説明します。Spine Locationは本の背の位置、Navigationはページの移動方向、Transition Styleはアニメーションの種類、Pag...
😮 1
6:56 AM
2つ設定する例
6:56 AM
(ためしてない)
Avatar
2つ入れる場合もvc配列の順序は表示順だ (edited)
Avatar
ってことはとりあえずisDoubleSidedじゃなければ
UIPageViewControllerに生えているviewControllersプロパティは常に先頭が現在表示しているVCという認識であっていますか?
これは合ってそうですね
Avatar
そうですね
7:03 AM
isDoubleSidedは盲点だった。ありがとうございます
👍 1
Avatar
UIImageView の座標系上の座標を、表示されている画像上の座標(画像のFit/Fillなどの変形前の1ピクセルが1の座標系での座標)に変換する簡単な方法( CGAffineTransform を取得するなど)って何かありますか?自力実装すればもちろんできますが、 UIKit が提供する API で。↓が出てきたのでないのかなと思っています。 https://stackoverflow.com/questions/26348736/uiimageview-get-the-position-of-the-showing-image
I have a UIImageView which shows an UIImage. The UIImage may change to other UIImage in different size, and the position and the size of the UIImage inside will change according according to it. My
Avatar
確かない気がします…
😢 1
Avatar
omochimetaru 4/23/2018 4:06 AM
僕も昔それほしいなと思ったけど無かった事があった
Avatar
結局↓こうなりました。 extension UIImageView { public var viewToImage: CGAffineTransform? { guard let image = self.image else { return nil } switch contentMode { case .scaleAspectFit: let viewSize = frame.size let imageSize = image.size if viewSize.width / viewSize.height < imageSize.width / imageSize.height { return UIImageView.viewToImageFittingHorizontally(viewSize: viewSize, imageSize: imageSize) } else { return UIImageView.viewToImageFittingVertically(viewSize: viewSize, imageSize: imageSize) } case .scaleAspectFill: let viewSize = frame.size let imageSize = image.size if viewSize.width / viewSize.height < imageSize.width / imageSize.height { return UIImageView.viewToImageFittingVertically(viewSize: viewSize, imageSize: imageSize) } else { return UIImageView.viewToImageFittingHorizontally(viewSize: viewSize, imageSize: imageSize) } default: fatalError("Unsupported `contentMode`: \(contentMode)") } } private static func viewToImageFittingHorizontally(viewSize: CGSize, imageSize: CGSize) -> CGAffineTransform { let scale = imageSize.width / viewSize.width let offsetY = (imageSize.height - viewSize.height * scale) / 2 return CGAffineTransform(a: scale, b: 0, c: 0, d: scale, tx: 0, ty: offsetY) } private static func viewToImageFittingVertically(viewSize: CGSize, imageSize: CGSize) -> CGAffineTransform { let scale = imageSize.height / viewSize.height let offsetX = (imageSize.width - viewSize.width * scale) / 2 return CGAffineTransform(a: scale, b: 0, c: 0, d: scale, tx: offsetX, ty: 0) } }
4:14 AM
ビュー座標系から画像座標系への座標変換行列を CGAffineTransform で得ます。 .scallAspectFit.scallAspectFill にしか対応してませんが。
4:15 AM
あ、演算子の実装が別にいるか。 大丈夫だった。 (edited)
Avatar
omochimetaru 4/23/2018 4:15 AM
レイアウトされた画像部分にラベルとかボタンを置くみたいになると結局自作ビューが欲しくなると思う
Avatar
@omochimetaru CGAffineTransform がだと独自クラスにしなくても単に重ねるとかやりやすいかなと。
Avatar
omochimetaru 4/23/2018 4:18 AM
ビューの変形に追従しようとしたらviewDidLayoutSubviewsでそのメソッドを呼び出すみたいになりませんか?
Avatar
それは必要そう。
4:20 AM
今はタップされた画像上の座標がほしかったのでとりあえずその目的は達成されました。
4:21 AM
ビューを配置だと viewToImage じゃなくて imageToView がほしいか( viewToImage から逆行列計算すればいいけど)。
Avatar
omochimetaru 4/23/2018 4:28 AM
今はタップされた画像上の座標
なるほど
Avatar
Kishikawa Katsumi 5/4/2018 9:00 AM
iOS 11からFrameの大きさが変更前と後で同じならinputViewが変わってもUIKeyboard関連のNotificationが呼ばれなくなるという変更があったみたいなんだけど、iPhone Xでは明らかに見た目の高さが変わってるのに通知されないからどうしようもないという問題があるみたいです。 再現プロジェクト https://github.com/kishikawakatsumi/UIKeyboardNotificationNotCalled ^ iPhone XでUSキーボードからToggleボタンを押すと、明らかにキーボードの高さが変わるので通知して欲しいけど通知されない。カスタムInputViewの高さを275以外にすると通知される。 iPhone X以外、例えばiPhone 7では高さが258(USキーボードから切り開ける場合。日本語のフリック入力キーボードの場合は216)のとき、同様に通知されないけどこれは見た目の高さは変わらないので実質的に問題にならない。
Contribute to UIKeyboardNotificationNotCalled development by creating an account on GitHub.
😳 4
9:00 AM
http://www.openradar.me/33990607 <= たぶん同じ問題。
9:04 AM
Workaroundとしては @IBAction func toggleInputView(_ sender: Any) { let wasFirstResponder = textField.isFirstResponder if wasFirstResponder { textField.resignFirstResponder() } if let _ = textField.inputView { textField.inputView = nil } else { let myInputView = UIView(frame: view.bounds) myInputView.frame.size.height = 275 myInputView.backgroundColor = .blue textField.inputView = myInputView } textField.reloadInputViews() if wasFirstResponder { textField.becomeFirstResponder() } } こんな感じで、resignFirstResponder()を挟む。それだけだとキーボードが閉じてしまうのでbecomeFirstResponder()も呼ぶ。同じメソッド内で呼ぶぶんにはRunLoopが回らないので最終的に何ごともなかったようにキーボードはそのまま(変換中の日本語入力などは確定されてしまう)。
Avatar
この問題iOS11の根本的な変更が原因だったんですね、 そういう現象があるなとは思ってたのですが、深掘りできていなかったので助かります。
Avatar
Kishikawa Katsumi 5/4/2018 9:11 AM
これ、難しいですね。iPhone Xで問題になってるのはたぶんSafe Areaなんだろうけど、カスタムInputViewをSafeAreaに付けても見た目の高さは合わないので、なんかどうしようも無い感じです。 たぶんOSのバグだと思うんですけど。
Avatar
Kishikawa Katsumi 5/4/2018 9:18 AM
11.4だと直ってるっぽいな。。。Radarしなくていいかな。。。?
Avatar
Kishikawa Katsumi 5/22/2018 3:39 AM
3:40 AM
ちょっと信じがたいけど、iOS 10から使えるscrollView.refreshControl = refreshControlのプロパティを使ってUIRefreshControlを設定すると、5秒目からの挙動のようにスクロールがガクガクする。 ^ は単調な上下の移動を繰り返してるだけなのです。ガクガクしてるのはUIRefreshControlが悪さをしている。 ワークアラウンドとしてiOS 9以前のようにaddSubview(refreshControl)すると発生しない。
😮 16
😱 1
Avatar
なんかrefleshControlのinset弄る機構、あんまり出来よくないですよね、毎回苦労するイメージある
Avatar
Kishikawa Katsumi 5/23/2018 9:34 AM
UIRefreshControlの品質は悪いと思います。
9:37 AM
9:37 AM
9:37 AM
小ネタ
9:38 AM
UIView.animate(withDuration: 1) { [weak self] in self?.visualEffectView.effect = UIBlurEffect(style: .light) } visualEffectView.layer.speed = 0 ^ 時間を止めて
👏 2
Avatar
omochimetaru 5/23/2018 9:38 AM
visualEffectView.layer.timeOffset = TimeInterval(slider.value) (edited)
Avatar
Kishikawa Katsumi 5/23/2018 9:38 AM
visualEffectView.layer.timeOffset = TimeInterval(slider.value) timeOffsetを使って任意の瞬間にできる。
😶 2
Avatar
omochimetaru 5/23/2018 9:38 AM
そんな技がw
9:39 AM
これってUIView.animate全般でそうなんですか?
9:39 AM
frameが移動するようなやつとか。
9:39 AM
ていうかここまでソースコードあるしやってみよ。
Avatar
Kishikawa Katsumi 5/23/2018 9:39 AM
アニメーション全般でそうです。厳密にはCore Animation(UIView.animateはCore Animationを使ってるだけなので全部と言っていいはず)
9:40 AM
上の小ネタの論点は2つあって、
9:40 AM
1つはvisualEffectView.effectnilとそれ以外の値でアニメーションするということ、
9:41 AM
もう一つはvisualEffectView.layer.speed = 0timeOffsetのテクニックですね。
9:41 AM
これはUIViewPropertyAnimatorを使うとfractionみたいなプロパティを使って同じようにもっと直感的に操作できるはず。
😃 1
Avatar
omochimetaru 5/23/2018 9:45 AM
frameも動かせた。 (edited)
👏 2
Avatar
Kishikawa Katsumi 5/23/2018 9:48 AM
この話題に関しては http://ronnqvi.st/controlling-animation-timing ^ という偉大な資料があるのでこれを一読しておけばOK
There is a protocol called CAMediaTiming which is implemented by CAAnimation, the base class of CABasicAnimation and CAKeyframeAnimation. It is where all the timing related properties – like duration, beginTime and repeatCount – come from. All in all the protocol defines ...
😃 2
Avatar
Navigationのinteractive popもこれの系でしたっけ
Avatar
Kishikawa Katsumi 5/23/2018 10:05 AM
はい。不明ですけど、interactive popのAPIでやることは進捗を設定するだけなので、実装は〜Transitioningのアニメーションを実行して止めた上で進捗を与えるという上と同様の実装になっているはずです。 (edited)
Avatar
すごい、こんなことできるんですね🙄
Avatar
omochimetaru 6/21/2018 3:12 AM
UIStackView, NSStackViewのレイアウトに関して、 横並べStackViewの高さ、 縦並べStackViewの幅、 StackViewのHugging, Clipping Resistance, それらが縦横で入れ子になって、中のViewのContent Hugging, Compression Resistance StackView自体に設定されたAuto Layout Constraint StackViewのFill設定 などが絡み合っている時に (edited)
3:13 AM
どういう手順でレイアウトが解決されていくか、 特にStackView固有挙動とAutoLayoutの統合に関して
3:13 AM
きちんと理解したいんですが、 良い資料とかあったら知りたいです。
Avatar
Kishikawa Katsumi 7/2/2018 7:48 AM
CALayer.shadowOpacity ってこれだけCGFloatじゃなくFloatなの初めて気づいた。
😃 1
Avatar
omochimetaru 7/2/2018 7:48 AM
バグっぽそう。
Avatar
Kishikawa Katsumi 7/2/2018 7:50 AM
でしょうねえ。Swiftじゃなったら問題ないし、きっとずっと気づかなかったけど。
Avatar
32ビットに納めたい理由があるのかな CALayer.opacity もですよね。
😃 1
Avatar
omochimetaru 7/2/2018 7:53 AM
なるほど、CGFloatだと32/64可変なのを嫌った可能性が。
😃 1
Avatar
UIView.alpha が CALayer.opacity のラッパーである可能性を考えると、 view.alpha = alpha; alpha == view.alpha が偽になる可能性があるということかな?
Avatar
Kishikawa Katsumi 7/2/2018 7:57 AM
意図的の可能性もあると。 (edited)
Avatar
Kishikawa Katsumi 7/3/2018 6:31 AM
https://github.com/kishikawakatsumi/ImageAssetBug ^ このコードはiPhone 7/7 PlusのiOS 10.3.1のシミュレータで実行すると画像をxcassetsから読み込むことができません。 まったく同じコードを違うデバイス、OSの組み合わせで実行すると画像は正しく読み込め、表示されます。 この問題がデバイスでも発生するかどうか知りたいのですが、どなたか「iOS 10.3.1が動いているiPhone 7か7 Plus」のデバイスをお持ちだったら試してもらえないでしょうか?
Contribute to ImageAssetBug development by creating an account on GitHub.
6:32 AM
原因はよくわかってないのですが、おそらくファイルに何か問題があるような感じです。ただし明らかにファイルが壊れているとかではないはずです。
Avatar
Kishikawa Katsumi 7/3/2018 7:02 AM
10.3だけじゃなくて10.2とかでも起こるな。10.xとiPhone 7/7 Plusだと起こるのかな。
7:07 AM
^ もし10.xが動いている7/7 Plusを持ってる人がいたらぜひおねがいします。
7:08 AM
普通に書いたら UIImage(named:) 使うと思うんですけど、このコードはSwiftGenがデフォルトで生成するコードと本質的に同じなので、デバイスでも起こるんだったらそれなりに大変な問題じゃないかと思います。
7:14 AM
あと、このサンプルではPDFを使ってるんですけど一部のPNGでも同じ現象が起こることを確認しています。
Avatar
iOS 10.x が動いている iPhone 6 なら持ってるんですが 😫 お力になれず 🙏
Avatar
10.3.2のiPhone6plusでは見れました
Avatar
iOS 10.3.3 の iPhone 6 でも表示できました。(ちょっと画像がぼやけました)
Avatar
Kishikawa Katsumi 7/3/2018 7:30 AM
誰か持ってるんじゃないかと思ったけど意外と難しそうですね。まあ幸いこれはユニットテストで確認できるので、誰も見つからなかったらデバイスファームとか使います。
Avatar
iOS10.xのiPhone7、1時間後に借りれそうなのでこの後検証して見ます
Avatar
Kishikawa Katsumi 7/3/2018 8:08 AM
ありがとうございます☺
Avatar
iOS10.0 iPhone7出ませんでした
Avatar
Kishikawa Katsumi 7/3/2018 8:30 AM
ありがとうございます。デバイスでも起こることがわかってよかったです。
😫 1
😰 1
8:32 AM
厄介な点は、UIImageはFailableイニシャライザだけど、UIのリソースを読む場合は名前が合っててnilが返るのはまずありえないから、そんなことがある場合は普通はそこでクラッシュするように書くだろうってことですね。
8:33 AM
良い点はシミュレータでも起こるのでユニットテストが書けるところですね。
Avatar
omochimetaru 7/4/2018 2:28 AM
iPhone7 iOS10.0 で表示されない現象が確認できました。UIImage.init(named:in:compatibleWith:) が nil になるんですね。
2:29 AM
UIImage.init(named:)だとnilにならない。へえ。
Avatar
Kishikawa Katsumi 7/4/2018 3:02 AM
どうもありがとうございます。bundleの引数は関係なかったので、サイズクラスがなんか関係あると思うのですが、なぜ6/8だと再現しないのかがそれだと不可解です。 ということで調べたらなんかおもしろそうな気もするんですが、ここからどうしたものかって感じですね。
Avatar
Kishikawa Katsumi 7/4/2018 3:17 AM
SwiftGen使ってる場合には、知らないうちに画像がnilになる恐れがある(データによる)ので、テンプレートを変えてUIImage(named:)を使うようにするか、 class ImageAssetTests: XCTestCase { func testLoadImages() { let allImages = Asset.allImages for imageAsset in allImages { XCTAssertNotNil(UIImage(asset: imageAsset), "\(imageAsset.name) should not be nil") } } } ^ こういうテストを書いてチェックする。
Avatar
これiOS10&iPhone7でも一概に表示されない訳ではなくてxcassetのアセットが特定の条件満たした時に発生するってことですよね
Avatar
Kishikawa Katsumi 7/4/2018 5:26 AM
はい。データによります。でその条件はよくわかってないです。PDF/PNGどっちでも起こりえます。
5:27 AM
もし深く調査するなら私の手元には7つほど再現するデータがあります。
Avatar
Sketchからpdfで書き出しているプロジェクトの688枚のアセットでテスト走らせて見ましたが特に問題ありませんでした。 1個くらいあるかと思ったのですが思ったよりもレアケースなのか(もしくはExportの手法に依存するのか
Avatar
UIKitってどのタイミングで描画処理が走るのでしょうか label.text = "hoge" label.alpha = 0.5 この場合描画は2回呼ばれるのでしょうか…?
Avatar
omochimetaru 7/27/2018 7:52 AM
NO
7:52 AM
内部でdirty flagが立って
7:52 AM
次のメインループで描画されますよ
7:52 AM
setNeedsDisplay が true の状態で次のサイクルに行くと draw() が呼ばれるという形
7:53 AM
レイアウトも同じで、 setNeedsLayout と layoutSubviews で同じしくみ。
👍 1
Avatar
ありがとうございます!なるほどですね… 自分で似たような実装をする場合は var text: String { didSet { setNeedsDisplay() } } var subText: String { didSet { setNeedsDisplay() } } みたいな実装にすれば大丈夫でしょうか?(差分検知は別で行うとして
Avatar
omochimetaru 7/27/2018 7:55 AM
そのとおりです〜〜〜
❤ 1
Avatar
ありがとうございます!!
Avatar
CGPathで変なものが起きてバグかな let fullPath = UIBezierPath(rect: view.bounds) let tempPath = UIBezierPath(roundedRect: CGRect(x: 100, y: 100, width: 50, height: 50), cornerRadius: 16) fullPath.append(tempPath.reversing()) shapeLayer.path = fullPath.cgPath
1:37 AM
height = 50 cornerRadius = 16
1:38 AM
height = 50, cornerRadius = 17
Avatar
cornerRadiusがheightの0.32倍 -> 0.33倍に変化する時、描画されたcornerRadiusがheightの0.5倍になった
Avatar
UIWindowをkeyにせずにvisibleにする方法ってありましたっけ
6:23 AM
デバッグ情報が乗ってるUIWindowをアプリケーションのappdelegate.windowより高いレベルに置きたいんだけどkeyはappdelegate.windowにしておきたくて
6:24 AM
debugWindow.makeKeyAndVisible() debugWindow.resignKey() ってやってるんだけど一瞬メインのwindowがkeyじゃなくなることに何か問題ないかなというのが不安
Avatar
windowLevel
Avatar
Kishikawa Katsumi 8/6/2018 6:32 AM
うろ覚えだけどhiddenをfalseにすると表示されるはず。手前に持ってくるのはwindowLevel. makeKeyAndVisibleを呼ぶ必要はなし(これは自信あり)
6:33 AM
func configureExternalDisplayAndShowWithContent(rootVC : UIViewController) { let screens = UIScreen.screens() // Configure the content only if a second screen is available. if screens.count > 1 { let externalScreen = screens[1] let screenBounds = externalScreen.bounds // Create and configure the window. self.externalWindow = UIWindow.init(frame: screenBounds) self.externalWindow!.windowLevel = UIWindowLevelNormal self.externalWindow!.screen = externalScreen // Install the root view controller self.externalWindow!.rootViewController = rootVC // Show the window, but do not make it key self.externalWindow!.hidden = false } else { // No external display available for configuration. } } UIWindowのドキュメントにこんな感じで書いてあったから、同じようにしたらいいのではないかしら。
Avatar
おっ
6:47 AM
makeKeyAndVisibleを呼ぶ必要はなし(これは自信あり)
6:47 AM
なんと。
6:48 AM
ためしてみよう ありがとうございます
Avatar
Kishikawa Katsumi 8/6/2018 6:54 AM
昔のカスタムアラート系のOSSはおそらく似たようなことをしていると思うのでそれが参考になるかと。最近はUIPresentationControllerでステータスバーより上に出せるから使ってなさそう。
😃 1
Avatar
ウオー
6:58 AM
ありがとうございます 助かります
Avatar
tableViewのdidSelectRowからあるUIViewControllerをpresentする時、present呼ぶ前に、tableView.deselectRow(at: indexPath, animated: false)を呼ばないと、押すからpresentまで、何秒間かかったこともあります。。他に経験した人がいますかな😓
Avatar
私はないですね。present までの間でアプリを何回か一時停止させてみて、その時のコールスタックからその間何やってるかとか見られないです?
Avatar
@Kuniwak tableViewがcollectionViewCellの中にあるので、あれが関わってるかもしれない。 帰った後調べてみます、ありがとうございます。
3:34 AM
ちなみに、simulatorが問題ない、実機だけです。👀
Avatar
なるほど。。。
Avatar
"In tableView:didSelectRowAtIndexPath: you should always deselect the currently selected row." 公式ページで書いてありました。
Avatar
omochimetaru 8/29/2018 2:34 AM
DispatchSourceのタイマーの発火時刻がアプリがバックグラウンド状態の際に到達した場合、 次にアプリがフォアグラウンドになった瞬間にそのタイマーのイベントが発生するんですが、 UIApplicationのwillEnterForeground通知も同様にフォアグラウンドになった瞬間に呼ばれます。 観察した範囲ではこれらは常にタイマーイベントが先に発生しているんですが、 タイマーイベントとフォアグラウンドイベントの前後順って保証されているんですか? ドキュメントがあったら知りたいです
2:35 AM
もちろん真の時系列で言えばタイマーが発火したあとでフォアグラウンドになっているのでそのように動いてほしという気持ちなんですが・・・
Avatar
Undocumentedっぽいけど処理系から素直に考えると先だよなみたいなお気持ちはある
Avatar
omochimetaru 8/29/2018 2:36 AM
処理系から、とは?
Avatar
バックグラウンドになった時のアプリの挙動、Networkの読み込みが一時停止したりするの
Avatar
omochimetaru 8/29/2018 2:45 AM
関連記事等も見たけど、やっぱりその手の処理の中断処理の取扱についての説明が見つからない
Avatar
iOS の UIView 派生クラスで func draw(_:) を override して UIBezierPath やら UIImage やらを描画する横並びで、 文字列も描画するやつの話。 import UIKit すると NSString.draw(at:withAttributes:) や NSString.draw(in:withAttributes:) が使...
2:25 AM
ところでなぜだか NSString ではなく String のインスタンスでも NSString.draw(at:withAttributes:) が呼び出せる様子。
2:26 AM
これってどうしてなんですかね。
Avatar
omochimetaru 9/25/2018 2:29 AM
補完は出ないけどたしかに行けますね
Avatar
でも、 appendingPathComponent(_:) とかはダメですよね。
Avatar
omochimetaru 9/25/2018 2:30 AM
'lastPathComponent' is unavailable: Use lastPathComponent on URL instead.
2:30 AM
デフォルトがNSStringのメソッド全部呼べるのかな?
2:31 AM
The Swift Programming Language. Contribute to apple/swift development by creating an account on GitHub.
2:32 AM
@available(*, unavailable, message: "Use lastPathComponent on URL instead.") public var lastPathComponent: String { fatalError("unavailable function can't be called") }
Avatar
明示的にunavailable書かないと使えるはず
Avatar
omochimetaru 9/25/2018 2:32 AM
unavailableは↑で書かれてた
Avatar
ああ、なるほど。
Avatar
omochimetaru 9/25/2018 2:32 AM
draw(at:)は見当たらないから、デフォルトの、使える挙動になってる?
Avatar
NSStringのメソッドをStringに補完する機能があると、半年くらい前に話題になった記憶が朧げにあります
Avatar
omochimetaru 9/25/2018 2:33 AM
-dump-ast で見ると、暗黙の変換が出てくるんだったような
Avatar
それそれ
Avatar
lastPathComponentはFoundationで定義されているextensionだけど、draw(at:)はUIKitで定義されているextensionだから。
Avatar
omochimetaru 9/25/2018 2:35 AM
import UIKit ができないから、コマンドラインで試せないや
Avatar
ナルホド
2:35 AM
やべぇな、じゃあサードで書いたextension全部出てくるのか
Avatar
omochimetaru 9/25/2018 2:35 AM
The Swift Programming Language. Contribute to apple/swift development by creating an account on GitHub.
2:35 AM
UIKit側のオーバレイにStringは無さそう
2:36 AM
ここに書けば同じように潰すことはできそうだけど。
Avatar
明示的に unavailable にするのは意図を持ってやってるんだと思うけど、今の状態だとちょっと中途半端ですね。
Avatar
あーギョムコードのNSStringのextensionも、Stringから使えちゃうんじゃないかな。
Avatar
omochimetaru 9/25/2018 2:40 AM
ギョムコードで String の extension も書いて潰そう
Avatar
framework分けたから考えなくてよくなった
Avatar
omochimetaru 9/25/2018 2:41 AM
importしなければ関係ないから?
Avatar
そだね
2:41 AM
本体コードはどうやってもimport出来ないから安心
Avatar
The Swift Programming Language. Contribute to apple/swift development by creating an account on GitHub.
2:48 AM
この辺りが unavailable の意図っぽいですね。
2:50 AM
あ、リンクはったところよりもうちょっと上の方。
Avatar
norio_nomura 9/25/2018 5:38 AM
$ echo 'import UIKit; "test".size()'|swift -frontend -dump-ast -sdk `xcrun --show-sdk-path --sdk iphonesimulator` -target x86_64-apple-ios12.0 - (edited)
5:41 AM
-dump-astの方が判りやすいのか。 (source_file (import_decl trailing_semi 'UIKit') (top_level_code_decl (brace_stmt (call_expr type='CGSize' location=<stdin>:1:22 range=[<stdin>:1:15 - line:1:27] nothrow arg_labels= (dot_syntax_call_expr type='([NSAttributedString.Key : Any]?) -> CGSize' location=<stdin>:1:22 range=[<stdin>:1:15 - line:1:22] nothrow (declref_expr type='(NSString) -> ([NSAttributedString.Key : Any]?) -> CGSize' location=<stdin>:1:22 range=[<stdin>:1:22 - line:1:22] decl=UIKit.(file).NSString.size(withAttributes:) function_ref=single) (bridge_to_objc_expr implicit type='NSString' location=<stdin>:1:15 range=[<stdin>:1:15 - line:1:15] (string_literal_expr type='String' location=<stdin>:1:15 range=[<stdin>:1:15 - line:1:15] encoding=utf8 value="test" builtin_initializer=Swift.(file).String.init(_builtinStringLiteral:utf8CodeUnitCount:isASCII:) initializer=**NULL**))) (tuple_shuffle_expr implicit type='(withAttributes: [NSAttributedString.Key : Any]?)' location=<stdin>:1:26 range=[<stdin>:1:26 - line:1:27] tuple_to_tuple elements=[-3] variadic_sources=[] default_args_owner=UIKit.(file).NSString.size(withAttributes:) (tuple_expr type='()' location=<stdin>:1:26 range=[<stdin>:1:26 - line:1:27]))))))
Avatar
https://github.com/apple/swift/blob/master/lib/Sema/CSSimplify.cpp#L3233-L3238 String/NSString 間でしかこの暗黙変換は起きないっぽい?
The Swift Programming Language. Contribute to apple/swift development by creating an account on GitHub.
😲 1
Avatar
omochimetaru 9/25/2018 9:24 AM
オー String特別扱いだ (edited)
Avatar
let maskLayer1 = CALayer() let maskLayer2 = CALayer() let layer = CALayer() maskLayer2.mask = maskLayer1 layer.mask = maskLayer2 これなんか動かない気がする 2つのMaskの共通部分でマスクしたいが、片方のマスクだけ適用される。 ちなみにNimble_snapshotだとちゃんとマスクされた状態のスクショが生成されてた (edited)
Avatar
Contribute to noppefoxwolf/NestedMaskLayerIssue development by creating an account on GitHub.
Avatar
いきなりすみません、ここってUIKitに関する質問ならしてもよろしいのでしょうか?
Avatar
どうぞどうぞ
Avatar
ありがとうございます
Avatar
UICollectionViewで縦方向のページングを楽してcollectionView.isPagingEnabled = trueで実装したのですが(ページングするCellのサイズはUIScreen.main.bounds.heightです)若干ずれてしまっています。 標準のページングのサイズっていくつなのでしょうか?やはり、自前のページングアニメーションを実装したほうが良いのでしょうか?
Avatar
Kishikawa Katsumi 9/28/2018 1:21 AM
UIScrollViewにおける isPagingEnabled = true の時の1ページぶんの大きさは自身のboundsになります。
1:22 AM
セルのサイズを1ページとしたいとき、boundsとセルの大きさが異なるなら、その分すこしずつずれていきます。
Avatar
https://github.com/haruevorun/ApiClient-TimeLine/tree/myfeature 一応それ用のプロジェクトをつくってみました
Contribute to haruevorun/ApiClient-TimeLine development by creating an account on GitHub.
1:23 AM
なるほど、ありがとうございます
1:24 AM
そのUIScrollViewのboundsは今回ならUICollectionViewのboundsという認識でよろしいですか?
Avatar
Kishikawa Katsumi 9/28/2018 1:24 AM
そうです。
Avatar
collectionView.frame.heightで良さそう
1:25 AM
scrollViewのboundsってcontentSize帰ってきませんか? (edited)
Avatar
Kishikawa Katsumi 9/28/2018 1:26 AM
frameだっけ
1:27 AM
いや、boundsの幅と高さはframeと一致するんじゃないかな。 ScrollViewにおけるboundsは現在表示している領域を表すので。
1:27 AM
(^ 話ずれています。念のため)
Avatar
勘違いかな、失礼しました
Avatar
Kishikawa Katsumi 9/28/2018 1:28 AM
いや、私も記憶で書いてるので後で確認しましょう。
1:29 AM
ページングの話だと、この例だと、セルのサイズとCollectionViewの大きさを合わせて(縦方向を短くする)ClipToBoundsをFalse、っていうのが基本テクニックだと思います。
Avatar
あと、CollectionViewのcontentInsetはどこかの記事でtopが64.0で
Avatar
Kishikawa Katsumi 9/28/2018 1:30 AM
それで表示はだいたい希望通りになるので、あとは大きさが小さくなってスクロールエリアが減った部分をどうごまかすか、みたいな感じです。
😀 1
❤ 1
Avatar
bottomが49.0みたいなのを見た記憶があるのですが
1:31 AM
contentInsetをすべて0にはできないのでしょうか?
Avatar
Kishikawa Katsumi 9/28/2018 1:32 AM
contentInsetはどこかの記事でtopが64.0、bottomが49.0
これはナビゲーションバーとタブバーがある画面にUIScrollViewを置いた場合に自動で調整される値のことですね。
1:33 AM
この例だと、ナビゲーションバーもタブバーも存在しないので、contentInsetはゼロだと思います。
Avatar
statusbarがありませんか?
Avatar
こういった感じでした (edited)
Avatar
Kishikawa Katsumi 9/28/2018 1:34 AM
あ、そうですね。ステータスバーのぶんが調整されてるかも。Topに正の値が入ってそう。
Avatar
なるほど
Avatar
Kishikawa Katsumi 9/28/2018 1:35 AM
ナビゲーションバーやタブバー、ステータスバーがある場合にゼロにしたいなら、コレクションビューを上下のバーに重ねずにその端から配置します。
1:35 AM
要するに上端と下端をSafeAreaに付けます。
Avatar
なるほどありがとうございます!
Avatar
Kishikawa Katsumi 9/28/2018 1:37 AM
ナビゲーションバーや、タブバーはブラー効果がかかっていて微妙に透過して裏のコンテンツが見える、というのが標準の挙動なので、スクロールするビューはナビゲーションバーや、タブバーに重なるように配置して、重なるぶんのInsetを調整する(自動でなされる)というのがデフォルトの作りです。
1:37 AM
contentInsetが〜という記事はおそらくそのことについて書かれたものだと思います。
Avatar
ありがとうございますm( )m
Avatar
すみませんPhotosに関する質問はどこですればよいのでしょうか?
6:54 AM
PHImageManager().requestImageでimageがnilになってしまう問題が発生してしまいまして、、、、。
Avatar
omochimetaru 10/9/2018 6:54 AM
#ios とか #uikit とかで良いと思います。
Avatar
ありがとうございます!
Avatar
yutailang0119 10/9/2018 6:55 AM
エスパーだけど、こんなはまりだったりせしませんか(手前味噌) https://qiita.com/yutailang0119/items/53071493a4ec2eca3f5f
Avatar
いやぁiCloudの画像は取得していないはずなのですが、、、、
6:57 AM
デフォルト設定で取得されていたら別ですが、、
6:57 AM
前提・実現したいことswiftで日記アプリを作っています。 実現したいことは、ユーザーのライブラリから写真データを取得して一覧表示し、写真選択機能を作成することです。 発生している問題・エラー...
6:58 AM
こちらでも似たような問題が発生してるのですが、私の場合optionはPHImageRequestOptionsDeliveryMode.fastFormatで
6:58 AM
外してみたりしてみましたがやはりnilが出てしまいました
Avatar
Kishikawa Katsumi 10/9/2018 6:59 AM
コールバックにuserInfoのディクショナリが返ってきているはずですが、そこの内容はどうなってますか?
Avatar
Optional([AnyHashable("PHImageResultWantedImageFormatKey"): 10000, AnyHashable("PHImageFileUTIKey"): public.jpeg, AnyHashable("PHImageFileSandboxExtensionTokenKey"): 9e8ebb3d3a0d41305e44aec69fe778a9d5c80e6a;00;00000000;00000000;00000000;000000000000001a;com.apple.app-sandbox.read;01;01000005;0000000000069af6;01;/private/var/mobile/Media/DCIM/100APPLE/IMG_0030.JPG, AnyHashable("PHImageResultIsInCloudKey"): 0, AnyHashable("PHImageFileURLKey"): file:///var/mobile/Media/DCIM/100APPLE/IMG_0030.JPG, AnyHashable("PHImageResultIsPlaceholderKey"): 0, AnyHashable("PHImageResultIsDegradedKey"): 0, AnyHashable("PHImageFileOrientationKey"): 0, AnyHashable("PHImageResultDeliveredImageFormatKey"): 10000])
7:03 AM
これでしょうか?
Avatar
Kishikawa Katsumi 10/9/2018 7:05 AM
関係ないけどUndocumentedなKeyが結構あるんですね。。。
7:06 AM
file:///var/mobile/Media/DCIM/100APPLE/IMG_0030.JPGって返ってきてるから、アクセスできてそうですけどねえ。
Avatar
今実装しているのが、PHAssetを配列で取得したあとにcollectionViewCellに渡してからUIImage化しているのですが
7:08 AM
それとは別に単体でrequestImageしたときは正常に動いていました。
Avatar
すみません、解決しました!
7:22 AM
複数リクエストしてたのでデータは取得できていたのですがクロージャーが呼ばれる前にguard文に引っかかってエラーを起こしていました、、、、。
Avatar
PhotoKitはiOS8のリリース当初からUndocumentedなキーばかりで、画像のRawデータ扱うときにめっちゃハマりました。。。
Avatar
Kishikawa Katsumi 10/17/2018 12:18 PM
Contribute to kishikawakatsumi/AutoLayoutManiacs development by creating an account on GitHub.
12:20 PM
Strech & Sticky Header
12:21 PM
Expand & Collapse Long Text
12:21 PM
Table Column Layout
12:22 PM
AutoLayoutの実装を競いつつ知見を共有するような何かをしたくて、問題を考えました。 上記はデモとリファレンス実装です。
12:26 PM
レギュレーションは、
  • 静的なAutoLayoutの制約だけで動く方が高評価
  • 動的なビューの追加削除、制約の追加削除・変更はマイナスポイント
  • UIStackViewのisHiddenを切り替えるのは静的であるという扱い という感じで、動的な要素を排除し静的な定義のみで作られたビューはメンテナンス性が高いということを目指そうというものです。
12:28 PM
上の例はStoryboardだけで作られていてレイアウトに関するコードは全然書かれてなくて、自分でもなかなかよく書けたんじゃないかと思います。 で、もっとよい実装はありそうだからそれを見たいし、上のコードもアニメーションとかを気にし始めると納得いかない動作があるので、それを改善するにはどうすればいいかとかを話したい。
Avatar
おもしろそう
Avatar
上の例はStoryboardだけで作られていてレイアウトに関するコードは全然書かれてなくて、
確認してきてマジか・・・ってなった。
Avatar
yutailang0119 10/18/2018 2:07 AM
ヘッダー部分、これだけで実装できるのか...
Avatar
Kishikawa Katsumi 10/18/2018 2:31 AM
ありがとうございます。きっとおもしろいと思うんですよ。実装対決。 書き忘れたレギュレーション、
  • Deployment Targetは >= 11.4
  • viewDidLoadかloadViewに書くならコードで制約をつけるのはもちろんアリ
  • SnapShotTestを用意する予定で、それを通ればクリア、採点はみんなでコードを読みながらする こんな感じですかね。
2:35 AM
ちなみに、ネットサーフィンしてたら見つけたこの記事 https://medium.freecodecamp.org/tutorial-creating-stretchy-layouts-on-ios-using-auto-layout-3fa974fa5e28 が最高でした。 ヘッダーをAutoLayoutだけで作る解説ですけど、レイアウトブレイクを使って切り替える手法の応用範囲はかなり広いので、AutoLayoutを高レベルに使いこなせるようになるはず。 サンプルコードが各ステップごとにチェックアウトできるようにコミットされているので、1つずつ試して理解しながら読める構成も良い。
We’ll show you how to build a simple stretchy layout effect using Auto Layout, and then add some polish for iOS 11 and iPhone X
👀 3
Avatar
@Kishikawa Katsumi AutoLayoutManiacs面白いですね、実装真似ながら自分でも制約をつけていて気がついたのですが、Header Image ViewのTopからViewのTopへの制約はどのようにして付けているんですか?
Avatar
Kishikawa Katsumi 10/22/2018 5:13 PM
Header Image ViewとViewを選択して(Cmd+クリック)、AlignmentツールをクリックしてTopを合わせる、ですね。
5:14 PM
隣接するビュー以外のビューと制約をつける場合、および現在の位置関係が狙いと異なるビューの場合、^ のようにする方が簡単な場合が多いです。
5:15 PM
例えばSafeAreaじゃなくてルートViewと制約をつけたい場合なども、ViewとルートViewを選択してアラインメントツールのTop/Bottomとあわせる、とします。
5:16 PM
上下左右の位置関係が合ってる場合は、Ctl+クリックでVertical/Horizontal Spaceを使うこともあります。
Avatar
なるほど…確かにこれなら離れた階層でも制約が付けられるのですね、こういった制約つけた事なかったので勉強になります
Avatar
Kishikawa Katsumi 10/22/2018 5:20 PM
直接のスーパービューではないビューに付けた制約は、それで満たしているように見えてもStoryboardのLintがエラーを出すことがあって、 複雑になってくるとそれを回避するためにRemove on build timeの制約をつけるなどする必要があったので、あまりやりすぎるのも問題かなと思いましたが、
5:21 PM
ダイナミックな要素をなくせるのは魅力なので、もうちょっと可能性を探りたいですね。
5:22 PM
ちなみに今のリポジトリの状態よりちょっとだけ制約を減らせたので今度アップデートします。
🎉 2
Avatar
@Kishikawa Katsumi さんの実装と、記事の紹介、僕もすごくためになりました。ありがとうございます👏 結構いい感じ?に出来た気がします。実装対決で他の方のコード読むのが楽しみです。
😍 1
Avatar
Kishikawa Katsumi 10/24/2018 7:49 AM
This NSLayoutConstraint is being configured with a constant that exceeds internal limits. A smaller value will be substituted, but this problem should be fixed. Break on BOOL _NSLayoutConstraintNumberExceedsLimit(void) to debug. This will be logged only once. This may break in the future. ^ AutoLayoutで遊んでたらこういうログを見た。 OS バージョンで閾値は異なるようです。
😮 1
Avatar
もしご存知の方がいらっしゃいましたら教えて頂きたいのですが、 ガギグゲゴザジズゼゾダヂヅデドのような値を UILabelのtextに設定するとアプリが落ちるのですが、 こういった現象に遭遇して解決された方いらっしゃいませんでしょうか? (これらの文字を削除するとうまく設定することができています。)
Avatar
Kishikawa Katsumi 10/24/2018 9:06 AM
@shiz 問題が再現するサンプルプロジェクトを共有できないですか?
9:09 AM
さっとやってみたところ、単純にそのテキストを設定するだけではクラッシュしないようなので、何か他に原因があると思います。
Avatar
@Kishikawa Katsumi ありがとうございます。 すいません問題となっているのは「シヨ」でした🙇 プロダクションコードで検証していたのでサンプルはまだ用意できていません🙇 ただ、私の方でも新規にプロジェクト作成して単純に文字列を設定するだけだと上手く行きました。 今回いくつか原因があるようです。 まずUILabelが通常のUILabelではなく 画面比率に合わせてフォントサイズを調整するカスタムのUILabelを使用していたので、 それを通常のUILabelに直接文字列で設定した場合は大丈夫になりました。 ただ、APIから返ってきた値をstructの変数に入れ、それをtextに設定するとまだ落ちるようです。 他に原因がありそうなのでもっと調べてみます。 ご回答ありがとうございます!
Avatar
スタックトレース見てみたいです、どこで止まっているのか
Avatar
@noppe 貼らせて頂きます🙇🏻‍♂️ 動き的にはException Breakpointでもキャッチできませんでした。 あとずっと文字が原因だと思っていたのですが、 どうやらtableViewのreloadDataを行う際にエラーになっているようです。 APIからの戻り値をセルに設定しているので、 メインスレッドが問題なのかとも思ったのですが、 DispatchQueue.main.asyncを使ってもエラーになります。 それでさっき気がついたんですが、iOS12だと起きなくて、iOS11.4だと起きています。 同じ端末でiOS11.4でエラーになりアップデートしてiOS12にしたら上手くいくようになりました。 また、iOS11.4でもデータが異なると上手くいくこともあり、 まだまだ調べることがありそうなので原因精査します🙇🏻‍♂️ (edited)
😮 2
Avatar
Autolayout周りでinfな制約付けたりすると↑みたいな位置で止まったりするのでデバッグコンソールに出てるログよく見てみるといいかもしれないです。
👍 1
Avatar
ちょっと臭そうな箇所があるので見てみます!ありがとうございます!
❤ 1
Avatar
ひとまず上記の現象を解消することができました。 (根本的な原因が何かが特定はできていませんが。。。) @noppeさんのご推察の通りAutoLayoutに関係するものでした。 今回設定していたのはUITableViewCellの中に垂直のStackViewを入れ、 その中に水平のStackViewを入れ、その中のUILabelに値を設定するというものでした。 こんな設定です↓ UITableViewCell -> 垂直のStackView -> 水平のStackView -> UILabel(numberOfLines = 0) <- ここに値を設定 解決方法としては、UILabelをUIStackViewの外に出してあげたら動くようになりました。 どこのレンダリングが原因かというのはわかっていませんが、 おそらくiOS12でAutoLayoutのレンダリングの性能が上がったことで iOS12では動いたのかなと思っています。 (そもそもの設定方法が怪しいのかと疑ったのですが、 Dispatch.main.asyncAfterで10秒くらい待った後に設定しても落ちていたので違うのかなと考えています。) 何はともあれ、始めにUILabelが原因ではないのでは、とアドバイスをくださった @Kishikawa Katsumi さん、 AutoLayoutが怪しいと教えてくださった@noppeさん、ありがとうございました! (edited)
🦊 1
Avatar
UICollectionViewCellってUITableViewCellと違ってselectionStyleがないんですね https://developer.apple.com/documentation/uikit/uitableviewcell/1623221-selectionstyle タップ中に見た目を変えるには collectionView(_ collectionView: UICollectionView, didHighlightItemAt indexPath: IndexPath) collectionView(_ collectionView: UICollectionView, didUnhighlightItemAt indexPath: IndexPath) の実装が必要そうですが、それにしてもcolorの設定とか必要になるわけですね なんかこう、そういう大層なやつじゃなくて、一発でお手軽にcellをグレーアウトさせる方法はないのでしょうか? そういう場合はcellの選択に任せず、内部でUIButtonを使う…というのが定石になるのでしょうか
Avatar
cellのサブクラス作ってsetHighlightとかをoverrideするのが良さそう
Avatar
あとタイミングの取得より気になっているのは、ハイライト時の見た目を細かく指定したくないということです 標準の、例のグレーアウトしている見た目になってほしいのですが、そのようなAPIが見つからず悩んでいます
Avatar
Kishikawa Katsumi 11/5/2018 5:03 AM
標準で用意されている方法はまず selectedBackgroundView ですね。これはUITableViewCellの同名のプロパティと一緒で、ハイライトに使うものです。
5:05 AM
それで挙動に満足できない場合はsetHighlightedはないけどisHighlightedがあるのでそれでやるか、本当に細かくやるならDelegateで細かくタイミングを受け取ってやる、
5:05 AM
UICollection/TableView共に、UIButtonを載せるのはスクロールを奪って気持ち良さが失われるので簡単にやるぶんにはいいけどオススメではない感じです。
5:06 AM
セルの一部に載るのはいいけど、セル全体がボタンでそれが敷き詰められるとかなりスクロールの体験が悪くなるはず。
Avatar
岸川さんありがとうございます! selectedBackgroundView で期待通りの挙動を得られました。 気付いた点としては、
  • 初期状態ではselectedBackgroundView はnilであり、 UIView() をセットする必要がある
  • contentViewより背後に存在するので、contentViewの背景色が透明でない場合、見た目上機能していないように見える
  • bringSubview(toFront:) するべきではないので、contentViewに背景色が必要な場合は selectedBackgroundView の利用は諦める
  • そのケースでは、 isHighlighted のdidSetをトリガーにして見た目を更新する
(edited)
Avatar
highlightないのか!
Avatar
Kishikawa Katsumi 11/5/2018 6:01 AM
You can use this view to give the cell a custom appearance when it is selected. When the cell is selected, this view is layered above the backgroundView and behind the contentView.
selectedBackgroundViewは選択したときにちょっとだけ前に来るんですよ。 ただcontentViewよりは後ろなので、背景色をBackgroundViewで行けるならそれで。 どうにもならない場合はいろいろとカスタムすることになると思います。
Avatar
cell自身のbackgroundColorなどを設定するのは気持ち悪いなあと思っていました なるほど、基本の背景色設定は cell.backgroundView でやれますね
👍 1
Avatar
UICollectionViewでUITableViewのようなタップ時のハイライト欲しいと思って、最近試行錯誤してたけど、didHighlightItemやcellのisHighlightをoverrideしてdidSetで色変える手法だとタップ時は見た目変わらなくてホールドしてやっと見た目変わるので、微妙だと悩んでいたらタイムリーな! 参考にさせてもらいます (edited)
Avatar
Kishikawa Katsumi 11/8/2018 11:25 AM
前に共有したSwiftGenで生成したコードで特定のデバイス(iOS 10/iPhone 7)で特定の画像が読み込めない問題の画像がまた1つ見つかって、 ただ、次のようなコードでユニットテストをいろいろなOS/デバイスのパターンで動かしていたけどすり抜けてしまっていた。 class ImageAssetTests: XCTestCase { func testLoadImages() { let allImages = Asset.allImages for imageAsset in allImages { XCTAssertNotNil(UIImage(asset: imageAsset), "\(imageAsset.name) should not be nil") } } } 理由は xcodebuild build-for-testing -workspace $BITRISE_WORKSPACE -scheme $BITRISE_SCHEME -destination 'generic/platform=iOS Simulator' ENABLE_TESTABILITY=YES ^ のようにビルドして ... xcodebuild test-without-building -workspace $BITRISE_WORKSPACE -scheme $BITRISE_SCHEME -destination 'name=iPhone 7 Plus,OS=10.3.1' -only-testing:FolioTests/ImageAssetTests ... のようにテストしてたけどこれだと再現しなくて、
11:26 AM
xcodebuild build-for-testing -workspace $BITRISE_WORKSPACE -scheme $BITRISE_SCHEME -destination 'name=iPhone 7,OS=10.3.1' ENABLE_TESTABILITY=YES ^ のようにビルド時のDestinationからiPhone 7/OS 10を指定しないとダメだった。 謎の現象。
Avatar
AVSampleBufferDisplayLayerにUIImage -> CVPixelBuffer -> CMSampleBufferの流れで作ったSampleBuffer食わせても表示されないのですが、なにか条件必要なのでしょうか…? SampleBufferから取り出したCVPixelBufferは正しい画像を吐くのでoption周りが怪しそうなのですが
Avatar
カメラからの CMSampleBuffer -> CVPixelBuffer と UIImage -> CVPixelBuffer の Attachmentが違う可能性があるかも
5:53 AM
MTLTexture.geybytesからもらったCVPixelBufferを使ってCMSampleBufferを生成できないはこの原因
Avatar
ありがとうございます、カメラから受け取るSBのAttachment入れてみたらどうなるか試してみます
6:17 AM
from UIImage Optional(<__NSSingleObjectArrayI 0x2801f0a10>({})) AVCaptureSession Optional(<__NSSingleObjectArrayI 0x282f00170>({}))
6:18 AM
む、そもそもAVCaptureSessionのもCMSampleBufferのAttachmentには何も入ってなさげですね…
Avatar
すみません、CVPixelBufferのAttachmentだ
6:20 AM
CVBufferGetAttachments経由でもらえます
Avatar
Optional({ CVImageBufferColorPrimaries = "ITU_R_709_2"; CVImageBufferTransferFunction = "ITU_R_709_2"; CVImageBufferYCbCrMatrix = "ITU_R_601_4"; MetadataDictionary = { ExposureTime = "0.033328"; NormalizedSNR = "22.21105655007992"; SNR = "28.23165646335955"; SensorID = 852; }; })
6:25 AM
とれました! マニュアルで作りにくそうな値だ…
Avatar
しかし、CVImageBuffe~を入れただけだとダメそうですね
🤔 1
Avatar
あ、いけました! CMTimingInfoちゃんとincrementしないと映像出ないっぽいですv
8:35 AM
でも色が変、ColorSpaceかPixelFormatがどこかでおかしくなってそう
11:30 AM
踏んでしまった。
Avatar
9400って番号もすごいね
Avatar
すごいとは
Avatar
苦死 00
Avatar
よくわからんw
Avatar
Mirror触るだけでリークするのか。
11:32 AM
なんかそんな雰囲気の話題についての修正のPRを見た気がする
11:32 AM
masterで治ってそう
Avatar
11:51 AM
あとで試して見るか
Avatar
ProductでMirror触ってる(のは流石にないと思うけど)と大変そうですねこれ。
Avatar
loadSpecialReferenceStorage was missing a release to balance the call to swift_unknownObjectWeakLoadStrong. SR-8878 rdar://problem/44872927
Avatar
おー
12:56 PM
weakが問題だったのか!
Avatar
これが同じ話かどうかの確証はないけども。
Avatar
同じな気はするな〜
Avatar
_dynamicCastToAnyHashable assumed that _swift_convertToAnyHashableIndirect takes its argument at +1, but that is no longer the case. rdar://problem/44686587
12:57 PM
もうちょい最近のでこういうのもあったw
Avatar
Weak
12:58 PM
weakですね
12:58 PM
IBOutletからweak外せば治った
Avatar
おー
Avatar
ありがとう、これmasterがリリースされるのは次のバージョンのXcodeなのかな
Avatar
omochimetaru 12/3/2018 1:36 PM
よくわからない、5.0のリリース作業は進行中だけど、4.2.2?が呼吸で出ることもあるのかな?
Avatar
CASampleBufferDisplayLayer、transformでひっくり返せば左右反転で表示出来るんですね。 一回反転したやつレンダリングしてenqueueするよりも軽そう。
Avatar
transform を使ってアニメーションさせようとすると 開始位置がずれてしまうのですが、使い方おかしいところありますか?
4:17 AM
import UIKit import PlaygroundSupport class ViewController: UIViewController { override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) view.backgroundColor = .white print(view) let box = UIView() view.addSubview(box) box.bounds = CGRect(x: 0, y: 0, width: view.bounds.width - 40, height: view.bounds.width - 40) box.center = CGPoint(x: view.bounds.width / 2, y: view.bounds.width / 2 + 100) box.backgroundColor = .red box.transform = CGAffineTransform(scaleX: 0.8, y: 0.8) DispatchQueue.main.asyncAfter(deadline: .now() + 3) { UIView.animate( withDuration: 3, animations: { box.transform = CGAffineTransform.identity .translatedBy(x: 0, y: 200) }) } } } let vc = ViewController() vc.view.bounds = CGRect(x: 0, y: 0, width: 375, height: 667) PlaygroundPage.current.liveView = vc (edited)
Avatar
ドキュメントに書いてありました 🙇
5:11 AM
Use this property to scale or rotate the view's frame rectangle within its superview's coordinate system. (To change the position of the view, modify the center property instead.) The default value of this property is CGAffineTransformIdentity.
😃 1
Avatar
@tarunon 適切なスコープがなさ過ぎてここで聞いて良いかわからんですが、Mercari Tech Confのときに#imageLiteralハックについて聞きましたけど、そもそも個々のモジュールにリソースを持たせないようにして、全てmain Bundleから持ってくるみたいな仕組みになっていないのは何か理由があるんですか?
Avatar
分け始めたときに分けたのでそうなってるんですが、今今は統合していきたい考えです
Avatar
なるほど!ありがとうございます!
11:36 AM
問題が無いならそっちの方がシンプルだよなあ。将来的にDynamic Frameworkをやめられる可能性も出てくるし (edited)
Avatar
DynamicLibをやめる
まさにそれです
Avatar
main Bundle以外にリソースが絶対混入しないようにして、全部mainから読むのでいいのか
Avatar
mainBundleだと、AppExtensionで死ぬので、Bundle用のframeworkはあった方が良いかもです
12:26 PM
1つで良いので
👍 2
Avatar
UIImageViewのanimationImages、アニメーション中にstopAnimatingして直後に別のアニメーションをstartAnimatingすると再生されないような気がする
Avatar
omochimetaru 2/8/2019 8:50 AM
XIBの中でViewのbackgroundColorをXCAssetで定義したnamed colorに設定していると、 それがデコードされたコールスタックでプログラムからbackgroundColorを変更しても、 XIBにかかれていた方の色で表示される謎挙動で困っているんですが、 なにか知ってる人いますか・・・ 再現↓ https://github.com/omochi/ios-xib-named-color-bug
Contribute to omochi/ios-xib-named-color-bug development by creating an account on GitHub.
Avatar
omochimetaru 2/8/2019 9:02 AM
viewDidLoadの後でsetBackgroundColorが呼ばれている #0 0x00000001cc026b14 in -[UIView(Rendering) setBackgroundColor:] () #1 0x000000019f62629c in -[NSObject(NSKeyValueCoding) setValue:forKey:] () #2 0x00000001cc038fcc in -[UIView(CALayerDelegate) setValue:forKey:] () #3 0x00000001cb83c71c in -[NSObject(UIIBPrivate) _uikit_applyValueFromTraitStorage:forKeyPath:] () #4 0x00000001cb83dd08 in -[_UIColorAttributeTraitStorage applyRecordsMatchingTraitCollection:] () #5 0x00000001cb83cf0c in -[NSObject(_UITraitStorageAccessors) _applyTraitStorageRecordsForTraitCollection:] () #6 0x00000001cc01095c in -[UIView _traitCollectionDidChangeInternal:] () #7 0x00000001cc010c7c in -[UIView _wrappedProcessTraitCollectionDidChange:forceNotification:] () #8 0x00000001cc010f70 in -[UIView _processDidChangeRecursivelyFromOldTraits:toCurrentTraits:forceNotification:] () #9 0x00000001cc03970c in -[UIView(CALayerDelegate) layoutSublayersOfLayer:] () #10 0x00000001a3275b7c in -[CALayer layoutSublayers] () #11 0x00000001a327ab34 in CA::Layer::layout_if_needed(CA::Transaction*) () #12 0x00000001a31d9598 in CA::Context::commit_transaction(CA::Transaction*) () #13 0x00000001a3207ec8 in CA::Transaction::commit() () #14 0x00000001cbbaaf78 in __34-[UIApplication _firstCommitBlock]_block_invoke_2 () #15 0x000000019ec09f30 in __CFRUNLOOP_IS_CALLING_OUT_TO_A_BLOCK__ () #16 0x000000019ec09830 in __CFRunLoopDoBlocks () #17 0x000000019ec04824 in __CFRunLoopRun () #18 0x000000019ec040e0 in CFRunLoopRunSpecific () #19 0x00000001a0e7d584 in GSEventRunModal () #20 0x00000001cbb90c00 in UIApplicationMain () #21 0x0000000104169b30 in main at /Users/omochi/github/omochi/NamedColorBug/NamedColorBug/AppDelegate.swift:12
Avatar
↓ちゃんと読んでないけど、この件に触れてそう https://procrastinative.ninja/2018/07/16/debugging-ios-named-colors/
Debugging iOS Named Colors Jul 16, 2018 iOS Named Colors are awesome. Until they are not. I took LLDB for a spin to find out...
Avatar
omochimetaru 2/8/2019 9:21 AM
完全にこれだ・・・
9:24 AM
ありがとうございます、少なくとも僕だけじゃなくiOS11からあった問題ってわかって助かります
Avatar
この感じだと、XIBで指定しておいて、コードの方で変えるっていうのは想定外なんですかね。
Avatar
omochimetaru 2/8/2019 9:27 AM
内部で持っているtrait変更での処理するのを待機してるトークンなりフラグなりを、setBackgroundColorが呼ばれた時に破棄してくれればいいだけなんで、作りが悪いだけって気がしますが
9:28 AM
実際、コードで設定するのにXIBでも設定してるのは、レイアウトや見栄えをチェックしたいからで
9:28 AM
それはそれとしてパラメータによって動的に変わったりもするから、 シンプルに、 initしてプロパティ渡して切り替えて・・・ って実装にしたかった。
Avatar
ああ、なるほど。それはよくありそう。>レイアウトや見栄えをチェックしたいから
Avatar
Kishikawa Katsumi 2/8/2019 9:31 AM
Xcodeががんばればいいことだと思うけど、Named Colorの中身はきっとXIBにアーカイブされないんじゃないかな。
Avatar
omochimetaru 2/8/2019 9:32 AM
UIImageViewに設定する画像とかもXCAssetからUIImage(named:)で取ってくるのだから、UIColorも同じようにUIColor(named:)で取ってくるXIBにならなかったんですかね?
Avatar
Kishikawa Katsumi 2/8/2019 9:32 AM
そうですよねえ。
Avatar
omochimetaru 2/8/2019 9:33 AM
コード側で対策の仕組みを作り込むより、XIBで見栄え用に設定するところだけ諦めて直接カラー指定するのがバランス良いさそうかな・・・
Avatar
Kishikawa Katsumi 2/8/2019 9:36 AM
今回の場合だとそれが良さそうですね。 viewDidLoadで必ず上書きするわけなので、そのタイミングでそうなってるほうがいい。
Avatar
omochimetaru 2/8/2019 9:38 AM
ありがとうございます。これ踏んだのがUITableViewCellの背景色設定のためだったんで、ここにたどり着くまでにめちゃくちゃ迷走しました・・・
Avatar
Androidだとレイアウトファイル(iOSのXIB/Storyboardファイルに相当)の方に、レイアウト時にだけ見えるラベル文字列とかそういうのを設定できるんですけどね。見栄え確認用に。そういうのがあればいいのにな。
Avatar
omochimetaru 2/8/2019 9:38 AM
Named color、結局xibの中に色が埋め込まれてて、色を変えた後に開き直すと差分がでたりする。
9:39 AM
いや、これは、違うっぽいな
Avatar
Kishikawa Katsumi 2/8/2019 9:40 AM
なるほど。
Avatar
omochimetaru 2/8/2019 9:41 AM
<view contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="AnA-HA-I0a"> <rect key="frame" x="16" y="20" width="240" height="128"/> <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/> <color key="backgroundColor" name="redColor"/> </view>
9:41 AM
ん???
Avatar
Kishikawa Katsumi 2/8/2019 9:41 AM
場合による、のかな。
Avatar
これは別の話っぽい
Avatar
omochimetaru 2/8/2019 9:41 AM
<resources> <namedColor name="redColor"> <color red="1" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/> </namedColor> </resources>
9:41 AM
下の方になんか書いてあるな。
9:42 AM
XCAssetを変更した後、XIBを開くと、変更が発生して、↑この部分が変わった。
9:42 AM
IB上でプレビューするためのキャッシュな気がする
Avatar
ディスコ追ってなかったんですが、ツイートで言ってたのは↑のresourcesの部分に変更が走る話です。
9:49 AM
コレ自体は実行時に影響ないはず
Avatar
Kishikawa Katsumi 2/8/2019 9:50 AM
なかなか面倒な仕組みになっているな。
Avatar
カスタムビューで draw(_ rect:) をオーバーライドして CGContext 経由で描画しようとしてるんですが、ビューの高さを増やすと描画されなくなる現象にハマってます。何かわかる方いますか?↓の height を増やすと描画されなくなります。 import UIKit // `drawRect` fails when `height` is increased private let height: CGFloat = 2000 class ViewController: UIViewController { @IBOutlet private var scrollView: UIScrollView! private var heightConstraint: NSLayoutConstraint! override func viewDidLoad() { super.viewDidLoad() let drawRectView: DrawRectView = DrawRectView() drawRectView.translatesAutoresizingMaskIntoConstraints = false scrollView.addSubview(drawRectView) heightConstraint = drawRectView.heightAnchor.constraint(equalToConstant: height) NSLayoutConstraint.activate([ drawRectView.topAnchor.constraint(equalTo: scrollView.topAnchor), drawRectView.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor), drawRectView.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor), drawRectView.trailingAnchor.constraint(equalTo: scrollView.trailingAnchor), drawRectView.widthAnchor.constraint(equalTo: scrollView.widthAnchor), heightConstraint, ]) } @IBAction func pressButton(_ sender: UIButton) { // this does not make `drawRect` fail heightConstraint.constant += 1000 } } class DrawRectView: UIView { override func draw(_ rect: CGRect) { let context: CGContext = UIGraphicsGetCurrentContext()! print("\(#file) \(#line): frame=\(frame)") context.setLineWidth(6.0) context.setStrokeColor(UIColor.red.cgColor) context.move(to: .zero) context.addLine(to: CGPoint(x: frame.size.width, y: frame.size.height)) context.strokePath() } }
Avatar
踏んだことある気がする
Avatar
Contribute to koher/DrawRectFailureSample development by creating an account on GitHub.
Avatar
self.contentMode = .redraw
7:56 AM
これ入れてください
Avatar
omochimetaru 3/5/2019 7:56 AM
Avatar
@tarunon ありがとうございます!試してみます。
7:58 AM
↓にしてみましたが解決しませんでした・・・。 let drawRectView: DrawRectView = DrawRectView() drawRectView.contentMode = .redraw (edited)
Avatar
omochimetaru 3/5/2019 8:00 AM
isActive = trueを一括でやるstatic methodあるの知らなkッタ。
Avatar
@omochimetaru isActive = true は忘れてハマりがち・・・。
Avatar
omochimetaru 3/5/2019 8:00 AM
たびたび忘れる。
Avatar
何度もハマって探したら見つかった。
Avatar
omochimetaru 3/5/2019 8:01 AM
あれ?
8:01 AM
普通にcloneしただけだけど
8:01 AM
動きます。
Avatar
height 増やしたら動かなくない?
Avatar
omochimetaru 3/5/2019 8:02 AM
ボタンを押すたびに線が傾く
Avatar
ボタンを押すのでは起こらず
8:02 AM
hieght を増やして実行すると起こる
Avatar
omochimetaru 3/5/2019 8:02 AM
iOS 12.1.4 (16D57) Model: iPad (6th generation) (Model A1954)
Avatar
20000 とかにすると起こりがち
8:03 AM
draw(_ rect:) の結果が描画されなくなる height は環境によって異なって、シミュレーターだと機種によって 5000 - 9000 くらいの範囲で起こったけど、
8:03 AM
実機だともう少し大きな値じゃないと起こらなかった
8:04 AM
こちらの環境では、 XR のシミュレーターだと hieght = 8192 だと描画されるけど height = 8193 だと描画されなくなる・・・。 (edited)
Avatar
omochimetaru 3/5/2019 8:07 AM
初期値40000でも更新されました 変化がわずかだからわかりにくいけど
8:07 AM
あれ?
8:07 AM
printは呼ばれないです。
Avatar
ボタンを押すんじゃなくて、
Avatar
omochimetaru 3/5/2019 8:08 AM
再描画されてないのか、変形してるだけか
Avatar
height の値を変えてビルドして実行
8:09 AM
どうも後から変えたら大丈夫なわけじゃなくて、↓でもダメだった。 heightConstraint.constant += 10000
Avatar
omochimetaru 3/5/2019 8:09 AM
height = 2000 と 40000 で見た目が変化しますよ。
Avatar
1000 ずつ 10 回足せば OK だけど 10000 足すと描画されなくなった。
Avatar
omochimetaru 3/5/2019 8:10 AM
+= 10000 にしても動きました
Avatar
@omochimetaru let height = 40000 でビルドして実行しても赤線が描画されてるってこと??
Avatar
omochimetaru 3/5/2019 8:10 AM
はい
Avatar
400_000 とか 4_000_000 はどうでしょう?
Avatar
omochimetaru 3/5/2019 8:11 AM
2019-03-05 17:11:09.118307+0900 DrawRectFailureSample[10843:3204174] This NSLayoutConstraint is being configured with a constant that exceeds internal limits. A smaller value will be substituted, but this problem should be fixed. Break on BOOL _NSLayoutConstraintNumberExceedsLimit(void) to debug. This will be logged only once. This may break in the future. 2019-03-05 17:11:09.136346+0900 DrawRectFailureSample[10843:3204174] -[<CALayer: 0x282d91240> display]: Ignoring bogus layer size (1024.000000, 2777777.000000), contentsScale 2.000000, backing store size (2048.000000, 5555554.000000)
Avatar
こちらでは height を増やすと環境ごとに異なるある値を超えると描画されなくなって真っ白になる。
Avatar
omochimetaru 3/5/2019 8:11 AM
謎のエラーが出て描画されなくなった。
8:11 AM
CALayerの限界サイズがあるっぽい。
Avatar
大きすぎたみたいだね。
Avatar
omochimetaru 3/5/2019 8:12 AM
これの事?その間の症状があるって話ですか?
Avatar
こちらはそのメッセージは出てないしもっと小さいので
8:12 AM
let height = 8193 で起こる
8:12 AM
その internal limits とやらではなさそう。
Avatar
謎だなぁ。こちらの環境がおかしいのかな・・・。
Avatar
omochimetaru 3/5/2019 8:14 AM
iPhoneSEでも9000はいけますね
8:14 AM
iOS 12.1.4 (16D57)Model: iPhone SE (Model A1662, A1723, A1724)
Avatar
pressButtonscrollView.subviews[0].setNeedsDisplay() を追加して、ボタンを押すと、こちらでも 10000 前後で真っ白になる事象が発生しました。 iPhone XR 12.1 シミュレータ
🙏 1
Avatar
ああ、確かに pressButton で発生しないことがあったのは setNeedsDisplay してないからな可能性がありますね。
8:22 AM
こちらでも追加するとボタン連打で起こるようになりました。
8:22 AM
@omochimetaru シミュレーターではどうですか?
Avatar
どうもシミュレーターでしか問題が起こらなさそうです。実機でも起こったと思ってたのは単に限界サイズを超えていただけのようです。 (edited)
8:45 AM
それであれば確認が面倒ですが動作としては問題ない気がします。ありがとうございました。
Avatar
Kishikawa Katsumi 8/7/2019 5:28 AM
https://github.com/kishikawakatsumi/IBPCollectionViewCompositionalLayout iOS 13のCollection View Compositional LayoutsをiOS 12以前でも使えるように再実装したライブラリを書いています。 で、コードの互換性で困っていて(特にSwiftで使う場合)、 理想はDrop-in Replacementで、コードはそのままでiOS 10, 11, 12でも13でも動くのがやりたいです。 Objective-Cだけならなんとなくできそうな気がする、ただSwiftは同じコードだとXcode 11でビルド(iOS 13をBase SDK)したときに「このクラスはiOS 13からしか使えない〜」のチェックに引っかかって if #available() を書かないといけないです。そうすると結局2つのコードベースをメンテするのであまり嬉しくない。(そうは言ってもクラスが違うだけの同じコードになるから格段に楽ではある) 今考えているのはクラスにPrefixを付けて、それで書くようにしてもらって、iOS 13なら標準のAPIを、iOS 12以下ならライブラリのAPIにフォールバックする、という風にしようかと思いますがあまり気に入ってないので
Backport of UICollectionViewCompositionalLayout to earlier iOS 12 - kishikawakatsumi/IBPCollectionViewCompositionalLayout
5:28 AM
もっと良い方法があったら教えてほしいです。
5:30 AM
理想は let itemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1), heightDimension: .fractionalHeight(1)) let item = NSCollectionLayoutItem(layoutSize: itemSize) let groupSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1), heightDimension: .absolute(44)) let group = NSCollectionLayoutGroup.horizontal(layoutSize: groupSize, subitems: [item]) let section = NSCollectionLayoutSection(group: group) let layout = UICollectionViewCompositionalLayout(section: section) let collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout) ... ^ これでiOS 13でも12以前でもうまく動く(iOS 13では標準のAPIを使う)。Xcode 10ならうまく動きそう。Xcode 11でビルドしようとするとダメ。 現在は妥協して以下のように書くようにしようかと考えています。 (edited)
5:30 AM
let itemSize = IBPNSCollectionLayoutSize(widthDimension: .fractionalWidth(1), heightDimension: .fractionalHeight(1)) let item = IBPNSCollectionLayoutItem(layoutSize: itemSize) let groupSize = IBPNSCollectionLayoutSize(widthDimension: .fractionalWidth(1), heightDimension: .absolute(44)) let group = IBPNSCollectionLayoutGroup.horizontal(layoutSize: groupSize, subitems: [item]) let section = IBPNSCollectionLayoutSection(group: group) let layout = IBPUICollectionViewCompositionalLayout(section: section) let collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout) ... IBPプレフィックスをつける。美しくないし、あまり理解してもらえない気がする。
Avatar
omochimetaru 8/7/2019 5:50 AM
IBPUICollectionViewCompositionalLayoutを使う方式の場合、iOS13では標準のものを使う部分はどうやって実現するんですか?
5:55 AM
Objective-Cだったら、 #if __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_OS_13_0 typedef IBPUICollectionViewCompositionalLayout UICollectionViewCompositionalLayout #endif とやっておけば、ビルドが12以下を含む場合だけ、UICollectionViewCompositionalLayoutが使えて、12以下を切ったら、UICollectionViewCompositionalLayoutがUIKitを参照する、 というふうにできる気がしますが
5:55 AM
この方法だと、ビルドサポートが12を含む状況で、ビルドしたアプリをiOS13で動かした場合にも、コンパチ用が使われてしまう。
5:56 AM
あと、同じことをSwiftでやりたいけどSwiftの#ifだとiOSのサポートバージョンでの分岐はかけないっぽい?
Avatar
Kishikawa Katsumi 8/7/2019 5:58 AM
Classをスワップする感じでいけるんじゃないかなと思っています。そこはランタイム関数でうまくいけるんじゃないかな。
Avatar
omochimetaru 8/7/2019 5:59 AM
なるほど。
6:00 AM
それなら↑のtypedefで解決する? (edited)
Avatar
Kishikawa Katsumi 8/7/2019 6:01 AM
ObjCだけなら、12以下向けにcompatibility alias を用意しておいて(13にはなし)、13ではIBPをNS/UIのクラスにマッピングする、でいけるはず。ObjCも最近はAvailability チェックあるけど確か警告だいObjCはどこかで握り潰すことはできるので。 ただSwift はどこまでも連鎖するから簡単ではなかったです。
6:03 AM
プレフィックスをつける方法ならたぶん行けそうです。typedefじゃなくてcompatibility aliasで行けそうです。
Avatar
omochimetaru 8/7/2019 6:22 AM
If we were to go code-watching for Objective-C, what would we look for? Square brackets, ridiculously-long method names, and @’s. “at” sign compiler directives are as central to understanding Objective-C’s gestalt as its ancestry and underlying mechanisms. It’s the ...
6:22 AM
ほーー
Avatar
Kishikawa Katsumi 8/7/2019 6:27 AM
もしくはヘルパークラスのようなものを通じてそれ経由で使うと自動的にうまくいく、みたいなのもアリなんですけど、今回のAPIは関連クラスが多いからあまり簡単にならない気がしています。。。
6:27 AM
最初の入り口だけ分けたらいい、というようなやつだとそれは機能すると思うんですけどね。
Avatar
norio_nomura 8/7/2019 8:01 AM
NS_SWIFT_NAMEを使うとか?
8:01 AM
クラス名の差し替えに使えたかな?
8:09 AM
変えられそうだけど、これもビルド時に名前が決まってしまうか。
Avatar
Kishikawa Katsumi 8/7/2019 8:11 AM
let itemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1), heightDimension: .fractionalHeight(1)) ... 困っているのは違う名前にするのであればいいんですけど、同じ名前だと^ のようなコードに絶対 #if available の分岐を入れないといけないんですよね。 理想はXcode 11でビルドしつつ、下のOSには互換ライブラリが動く、なんですけどなんか手段ないですかねえ?
Avatar
norio_nomura 8/7/2019 8:19 AM
なるほど。とりあえず、まずはXcode 11でビルドできる様にする必要がありますね。
Avatar
Kishikawa Katsumi 8/7/2019 8:25 AM
できればコールサイトは変えずに実現したいんですけど(呼び出しを変えるなら、クラスの変更はiOS 12以下にしかやってないので)、プレフィクス付きで呼ぶならXcode 11で現状でも使えます。
Avatar
norio_nomura 8/7/2019 8:35 AM
手元でビルドしてみたけど、ビルドできないです。Xcode 11 beta 5 on Catalina
Avatar
Kishikawa Katsumi 8/7/2019 8:38 AM
あれ。
8:38 AM
調べてみます 😓
Avatar
norio_nomura 8/7/2019 8:39 AM
/Volumes/Macintosh HD/Users/norio/github/IBPCollectionViewCompositionalLayout/IBPCollectionViewCompositionalLayout/IBPUICollectionViewCompositionalLayout.h:20:42: error: expected a type - (instancetype)initWithSectionProvider:(IBPUICollectionViewCompositionalLayoutSectionProvider)sectionProvider; ^
Avatar
Kishikawa Katsumi 8/7/2019 8:43 AM
ははあ、ブロックの型のやつですね。わかります。
Avatar
Kishikawa Katsumi 8/7/2019 8:55 AM
@norio_nomura 直しました。少なくともビルドはできるようになりました 🙏
Avatar
norio_nomura 8/7/2019 9:07 AM
確認しました。フレームワークはビルドできる様になりました。
Avatar
Kishikawa Katsumi 8/7/2019 9:09 AM
どうもありがとうございます。なんか良いアイデアがあったら教えてください 😄
Avatar
norio_nomura 8/7/2019 9:12 AM
これは、実行時切り替えはif #availableを使うしかないのでは。
9:17 AM
IBPプレフィクスが付いたObjective-Cの実装が、内部でOSバージョンをチェックして、本来の型のインスタンスを返すとか? (edited)
Avatar
Kishikawa Katsumi 8/7/2019 9:29 AM
IBPプレフィクスが付いたObjective-Cの実装が、内部でOSバージョンをチェックして、本来の型のインスタンスを返すとか?
そのように考えています。それはたぶん可能だと思っていて、 さらに可能ならコールサイトを変えずに実現したいです。
9:30 AM
まあPrefixつきの呼び出しが違和感があまりなければ、上のように処理しつつ(iOS 13以上なら標準APIにディスパッチする) (edited)
9:32 AM
12以下をDropできる段階でIBPを全部置換して消してしまうだけで完了なので、まあ悪くはない感じではあります。 ただ、サンプルコードとかをそのままコピー&ペーストで使えないので、なかなか不便だと思うんですよね。
9:32 AM
呼び出し元の記述が変わってしまうと。
9:33 AM
開発時だけなんかしたらソースコードの互換性がある、とかでも良いかも。
9:35 AM
相手がUIKitじゃなかったらObjCは別名にしつつSwiftから見えるクラス名を標準に合わせてimportでなんとかする、みたいなのもできそうなんですけどUIKitだからimportしないわけにはいかないし。。。。
Avatar
omochimetaru 8/7/2019 9:35 AM
ただ、サンプルコードとかをそのままコピー&ペーストで使えないので、なかなか不便だと思うんですよね。
なるほど
9:38 AM
Swift側で、あなたのアプリのパッケージの中で、 typealias NSCollectionLayoutSize = IBP.IBPNSCollectionLayoutSize としてから使ってね、で、衝突は回避できそうですけど (edited)
Avatar
Kishikawa Katsumi 8/7/2019 9:40 AM
あ、それで行けるならそういうヘルパーファイルを用意しておいたらいいかも 🙇 試してみます。
9:41 AM
うまくいけば、X年後にそのファイルをただ消したらいい、とできるからそれはかなり理想的。
🙂 1
Avatar
norio_nomura 8/7/2019 10:12 AM
NS_SWIFT_NAMEを使って、Objective-C側をiOS 13の型に見せる方法を試してみたけど、NS_SWIFT_NAME@protocolに対応してなくてダメだった。Swift側でtypealias使った方が良さそう。 (edited)
Avatar
norio_nomura 8/7/2019 10:23 AM
あと、NS_SWIFT_NAMEで型名をiOS 13の型名に変えた場合、メソッドの実装が2つ(iOS 13とIBP)ある様にSwiftからは見えてしまい、Ambiguous use of 'fractionalWidth'みたいなエラーが沢山出てしまった。Objective-Cで型名の重複が起きた時と同じ状態なのかも。 (edited)
Avatar
Kishikawa Katsumi 8/7/2019 10:46 AM
あらら、そんな風になるのか!
Avatar
Kishikawa Katsumi 8/8/2019 2:29 AM
Ambiguous use of 'fractionalWidth'みたいなエラーが沢山出てしまった。
これはどういう場合になるんですか?私の環境だと補完には出てこなかったので、オリジナルのObjective~Cのメソッド名を入力してしまうことはないように思いました。 @norio_nomura
2:31 AM
あ、違うか。Xcode 11だと例えば fractionalWidth と書いていても fractionalWidthDimension も見つけてしまってエラーになる、ということか。
Avatar
norio_nomura 8/8/2019 2:47 AM
こんな感じ。 /Volumes/Macintosh HD/Users/norio/github/IBPCollectionViewCompositionalLayout/Example/Example/Samples from Apple/Basics View Controllers/SectionDecorationViewController.swift:30:64: error: ambiguous use of 'fractionalWidth' let itemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0), ^ UIKit.NSCollectionLayoutDimension:4:21: note: found this candidate open class func fractionalWidth(_ fractionalWidth: CGFloat) -> Self ^ IBPCollectionViewCompositionalLayout.NSCollectionLayoutDimension:3:21: note: found this candidate open class func fractionalWidth(_ fractionalWidth: CGFloat) -> Self ^ NS_SWIFT_NAMEが漏れてたのでちょっと修正。 (edited)
🙏 1
Avatar
norio_nomura 8/8/2019 3:14 AM
NS_SWIFT_NAMEを試してダメだった記録としてcommitを残しておきます。 https://github.com/norio-nomura/IBPCollectionViewCompositionalLayout/commit/6a905437b681fba42c06d707b85a655033cfe0d9 (edited)
Avatar
Kishikawa Katsumi 8/8/2019 5:47 AM
^ 上のエラーは 6a905437b681fba42c06d707b85a655033cfe0d9 の環境で起こるってことですか?それとも現在のmasterで起こります?私の環境で起こってないのでちょっと詳しく教えてください @norio_nomura 🙏
5:52 AM
@omochimetaru Availabilityのチェックは public typealias NSCollectionLayoutSize = IBPNSCollectionLayoutSize public typealias NSCollectionLayoutItem = IBPNSCollectionLayoutItem ... ^ このようなtypealiasで回避できたので、クロージャとEnumに問題があるんですけどなんとかなりそうです。 あとはランタイムでちゃんとスワップ できるのかどうかをトライしてみます。
Avatar
omochimetaru 8/8/2019 5:57 AM
おお。クロージャとenumの問題はどんなことですか?
Avatar
Kishikawa Katsumi 8/8/2019 6:00 AM
クロージャの場合は Cannot convert value of type '(Int, NSCollectionLayoutEnvironment) -> NSCollectionLayoutSection?' (aka '(Int, IBPNSCollectionLayoutEnvironment) -> Optional<IBPNSCollectionLayoutSection>') to expected argument type 'IBPUICollectionViewCompositionalLayoutSectionProvider' (aka '(Int, NSCollectionLayoutEnvironment) -> Optional<NSCollectionLayoutSection>')
6:01 AM
^ 単純に名前を合わせてもクロージャが返すものが違う型で返しちゃうから、というような感じかなと思ってます。 たぶんなんとかなるんじゃないかな。
6:03 AM
Enumは別の問題でObjective-Cの方で compatibility aliasが使えないので(確か @inerfaceにしか使えない。 protocolもダメでそれはオリジナルのプロトコルを変えたい名前のプロトコルに適合させる、というやり方を使っています)
Avatar
omochimetaru 8/8/2019 6:03 AM
ふむふむ、なるほど
Avatar
Kishikawa Katsumi 8/8/2019 6:04 AM
compatibility aliasが使えないので、そもそも名前を変えられてない、というのがあって、でもそれは同じ値を持つ別のEnumを用意してそれをtype aliasで行けるかなと思っています。
6:04 AM
上のクロージャももしかしたらIBPNSCollectionLayoutEnvironmentがプロトコルだから問題なのかな。
6:05 AM
まあ、なんとかなりそうというのは、全体的な問題じゃなくて、クロージャをとるメソッドもEnumも限られてるので、まあなんとかなるかなという感じです。
Avatar
norio_nomura 8/8/2019 6:24 AM
@Kishikawa Katsumi
上のエラーは 6a905437b681fba42c06d707b85a655033cfe0d9 の環境で起こる
そうです。masterは問題ないです。紛らわしくてごめんなさい 🙇
(edited)
Avatar
Kishikawa Katsumi 8/8/2019 6:33 AM
いえ、どうもありがとうございます。
Avatar
Kishikawa Katsumi 8/8/2019 7:29 AM
あともう少しEnumとクロージャがあるから同じ対応が必要そうだけど、現在用意しているサンプルに関しては https://github.com/kishikawakatsumi/IBPCollectionViewCompositionalLayout/pull/3 こんな感じで同じコードベースでXcode 10と11でビルドはできた。(typealiasを書けば) あとはiOS 13で実行しているときはUIKitを使うようにできればかなりいい感じかも。
Avatar
#ifはOSバージョン使えないのか
Avatar
omochimetaru 8/8/2019 7:34 AM
そうなんだよね。この話題の時に調べて気づいたんだけど。
Avatar
Kishikawa Katsumi 8/8/2019 7:36 AM
可能ならSwiftのtypealiasもFrameworkに混ぜてしまいたいけどできるんかな。
Avatar
omochimetaru 8/8/2019 7:38 AM
SwiftPMだったらObjcターゲットとSwiftターゲットをくっつけたターゲットをライブラリのフレームワークにしておいて、exportすればそれ自体はできそうですけど、 アプリからimport UIkitしてると、名前が衝突してしまうと思います
7:39 AM
typealiasをアプリのパッケージの方で定義していないと、UIKit.NSCollectionFoo と IBP.NSCollectionFoo が曖昧になる
Avatar
Kishikawa Katsumi 8/8/2019 7:40 AM
UIKit.NSCollectionFoo と IBP.NSCollectionFoo が曖昧になる
なるほど。確かに。
Avatar
Kishikawa Katsumi 8/10/2019 2:12 PM
https://github.com/kishikawakatsumi/IBPCollectionViewCompositionalLayout/pull/3 ^ これでiOS 13/12, Xcode 10/11の両方でだいたいそのまま使えるようになりました。 おもちさんのアイデアをいただいて、typealiasを羅列した IBPCollectionViewCompositionalLayoutInteroperability.swift を自分でプロジェクトにコピーしてもらう、ということにしました。
Avatar
omochimetaru 8/10/2019 2:13 PM
おお〜
Avatar
Kishikawa Katsumi 8/10/2019 2:16 PM
@implementation IBPUICollectionViewCompositionalLayout - (instancetype)initWithSection:(IBPNSCollectionLayoutSection *)section { if (@available(iOS 13, *)) { #if __IPHONE_OS_VERSION_MAX_ALLOWED >= 130000 return [[UICollectionViewCompositionalLayout alloc] initWithSection:section]; #else return nil; #endif } else { IBPUICollectionViewCompositionalLayoutConfiguration *configuration = [[IBPUICollectionViewCompositionalLayoutConfiguration alloc] init]; return [self initWithSection:section configuration:configuration]; } } イニシャライザで分岐してiOS 13以上と以下で違うインスタンスを返すというテクニックとも言えない力技で、特にRuntime APIを使う必要もなかった。
Avatar
omochimetaru 8/10/2019 2:17 PM
それだけでイケるなら平和でいいですね
Avatar
norio_nomura 8/10/2019 9:48 PM
さすがObjective-C
Avatar
あれ?そのif (@available(iOS 13, *))#if __IPHONE_OS_VERSION_MAX_ALLOWEDの順序だと、Xcode 10でビルドしてあるとiOS 13で動かないのでは? (edited)
Avatar
Kishikawa Katsumi 8/11/2019 1:21 AM
そんな気がしますね。。。NSClassFromSringで取らないといけないかな。。。
Avatar
omochimetaru 8/11/2019 7:02 AM
__IPHONE_OS_VERSION_MAX_ALLOWED がコンパイル時の分岐で、 @available が実行時の分岐だから、包み方を入れ替えるだけで良い? (edited)
7:03 AM
いや、ちがうか、Xcode10でビルドする限りUIKit側のシンボルがリンクできないから、やるならリフレクションになるのか
7:04 AM
nilになっちゃうのは良くないから組み換えは必要として、
7:04 AM
「Xcode10でビルドすると実行がiOS13でもUIKitが使われない」は、許容しても良いと思う。
Avatar
Kishikawa Katsumi 8/11/2019 2:04 PM
+ (instancetype)layoutAnchorWithEdges:(NSDirectionalRectEdge)edges { if (@available(iOS 13, *)) { return [NSClassFromString(@"NSCollectionLayoutAnchor") layoutAnchorWithEdges:edges]; } else { return [[self alloc] initWithEdges:edges]; } } まあこれで良いんじゃないかな? #if __IPHONE_OS_VERSION_MAX_ALLOWED >= 130000 はXcodeがundefined symbolと言ってくるので仕方なくつけたもので、こっちの方がシンプルだし。
Avatar
omochimetaru 8/11/2019 2:05 PM
NSClassFromStringだあ
2:06 PM
そっちのほうがシンプルかつXcode10でビルドしていてもiOS13実機のときにUIKitが使われるのがメリットですね
Avatar
Kishikawa Katsumi 8/20/2019 8:50 AM
NSDiffableDataSourceSnapshot が最新のBetaでStructに変わった。 (edited)
Avatar
Kishikawa Katsumi 8/22/2019 8:36 AM
Collection View Compositional Layoutsで盛大に壊れるバグを見つけた。
8:37 AM
let item = NSCollectionLayoutItem(layoutSize: NSCollectionLayoutSize(widthDimension: NSCollectionLayoutDimension.fractionalWidth(1), heightDimension: NSCollectionLayoutDimension.estimated(44))) item.contentInsets = NSDirectionalEdgeInsets(top: 10, leading: 10, bottom: 10, trailing: 10) let group = NSCollectionLayoutGroup.horizontal(layoutSize: NSCollectionLayoutSize(widthDimension: NSCollectionLayoutDimension.fractionalWidth(1), heightDimension: NSCollectionLayoutDimension.estimated(44)), subitems: [item]) let section = NSCollectionLayoutSection(group: group) let layout = UICollectionViewCompositionalLayout(section: section) Estimated heightとcontentInsetsを一緒に設定すると起こる。
8:38 AM
Contribute to kishikawakatsumi/CollectionViewCompositionalLayoutsBugIOS13beta8 development by creating an account on GitHub.
😞 1
Avatar
omochimetaru 8/22/2019 9:13 AM
最初どこがバグってるんだろう?って思いながら動画見てたらだんだん壊れていって笑った
Avatar
Kishikawa Katsumi 8/22/2019 10:01 AM
細かいところを見ていくとだんだん合ってるのか間違ってるのかわからない挙動が出てきた。難しい。
Avatar
Kishikawa Katsumi 8/23/2019 12:12 AM
だいたい機能は網羅したのでよかったらいろいろ試してバグを出してほしいです 🙏 https://github.com/kishikawakatsumi/IBPCollectionViewCompositionalLayout iOS 13で動かしたのと結果が違ったらバグなのでわかりやすいし、パズルみたいで楽しいんじゃないかと思います。 ただ、上の例のように明らかにUIKitがおかしいこともあります。あとセーフエリア周りは正しいのかバグなのかよくわからないのが多い。 (edited)
Avatar
Kishikawa Katsumi 8/31/2019 8:10 PM
Collection View Compositional Layoutsで無限ループに入るパターン。let item = NSCollectionLayoutItem(layoutSize: NSCollectionLayoutSize(widthDimension: .fractionalWidth(1), heightDimension: .estimated(44))) let group = NSCollectionLayoutGroup.vertical(layoutSize: NSCollectionLayoutSize(widthDimension: .fractionalWidth(1), heightDimension: .absolute(44)), subitems: [item]) let section = NSCollectionLayoutSection(group: group) let layout = UICollectionViewCompositionalLayout(section: section) https://github.com/kishikawakatsumi/CollectionViewCompositionalLayouts-InfiniteLoop (edited)
Avatar
Kishikawa Katsumi 9/12/2019 9:05 AM
systemBrown がiOSだけ無くなったのなんでなんだろう?
Avatar
Kishikawa Katsumi 9/16/2019 5:44 AM
上のcontentInsetsとestimatedSizeを一緒に指定するとおかしくなるっていうの、もしかしたらバグじゃなくて想定内、というかもともと禁止されている組み合わせっぽいな。下記のようなログが出ているのを見逃していた。 Attempting to add contentInsets to an item's dimension along an estimated axis. This layout axis insets will be ignored (however, any non-estimated axis insets will be applied). Please consider using the item's edgeSpacing or the containing group's interItemSpacing instead.
Avatar
textView(_:shouldInteractWith:in:) ってshould〜なのでクエリ想定であり、CQS(問いを発することで答えを変えてはならない)的にはそこで副作用起こしちゃいけないと思ってたんだけど、「You can use this method to trig...
まあDeprecated APIなので今は正しくはtextView(_:shouldInteractWith:in:interaction:)を使うべきで、そして実はそっちのドキュメントからは副作用を許可する記述は消えてるんだけど、かといって適切にalternative actionを...
I'm using the UITextView delegate method to do some custom work like opening a in-app browser when user tapping on URL or attachment: func textView(_ textView: UITextView,
Avatar
Kishikawa Katsumi 10/14/2019 3:41 AM
これはiOS 13のバグだからまずバグを置いとくと、このメソッドでURLを判定してPushとかPresentでいいと思います。 (edited)
Avatar
textView(_:shouldInteractWith:in:interaction:)true返しとけば概ね期待通りになって、 シングルタップでsafari開く、長押しで選択肢出る、とかじゃなかったでしたっけ カスタムする場合はinteractionの種類に応じていろいろやるで良いのでは、副作用もOK
3:43 AM
should系だからクエリ想定でそうやるべきじゃないのではっていう発想は共感するけど、 (edited)
3:44 AM
Apple系のshould系って、だいたいなんか実際にアクションが今起きる!っていうイベントとペアになってませんか?
3:44 AM
クエリというより、アクションに対するフック機能というか。
3:45 AM
Cocoaでも「ウィンドウ閉じるボタンを押した」の検出がshouldWindowCloseみたいな感じのメソッドだった気がする。
Avatar
Kishikawa Katsumi 10/14/2019 3:48 AM
UIKitみたいな巨大で長く使われてるソフトウェアで名前ルールだけで判断するのは無理だと思いますよ。 書いている人も変わってわけだし。
Avatar
それはそもそもありますね。うかつに名前から忖度しようとすると痛い目みるやつもたまにある気がする
Avatar
(_:will〜) -> Bool みたいなのを見かけるイメージはあったけど、副作用を許す(_:should〜)も他にもけっこうあるのかな シグネチャだけじゃわからない
Avatar
Kishikawa Katsumi 10/14/2019 3:50 AM
このデリゲートを作るにあたって、ただのフックポイントだけど名前をつけるならUIKitの名前に合わせてshould〜だろう、って付けたんじゃないかな。
3:52 AM
^ みたいなことが多分にあると私は考えていて、それは合理性があって、そもそも名前ルールは覚えられる範囲にしないといけないからそんなに細かいケースを拾えない。
Avatar
個人的にはフックはやめて didInteractwith... にしておいて、自分で invokeDefaultTextInteractHandler みたいに明示的にデフォルト挙動を実行するようなAPIのほうが好きだな。UIKitだとあんまり見かけないけど。
Avatar
textView(_:shouldInteractWith:in:interaction:) で副作用許すなら許すで別にいいんですが、 そうすると textView(_:shouldInteractWith:in:) で明記されていたその記述が https://developer.apple.com/documentation/uikit/uitextviewdelegate/1649337-textview から削除された動機がわからないんですよね
3:57 AM
フックはやめて didInteractwith... にしておいて、自分で invokeDefaultTextInteractHandler みたいに明示的にデフォルト挙動を実行するようなAPI UIKitだとあんまり見かけない
それだと「委譲」ではないから、かな
(edited)
Avatar
全体的にDiscussionのくだりの文が変わってるんで、書き換えたときに深く考えなかっただけじゃないかしら
3:59 AM
もし「だめになったから消した」なら、それこそimportantの枠の中で明記されると思う
3:59 AM
それだと「委譲」ではないから、かな
Delegateのノリが違うのか。
Avatar
書き換えたときに深く考えなかった
そんな気はしてる
Avatar
もしほぼコピペで1文落ちてたら僕もちょっと気にすると思う。
Avatar
とりあえずAppleにfeedback送っておきました
Avatar
このメソッドを使うかどうかでurlクリックの挙動が大きく変わるという悪夢があるんですよね、本当に辛い
4:26 AM
なので今一番マシなのがLongPressGestureRecognizerのstate=endで、locationからattribute取ってきて.linkを抜き出して発火、になると思います
Avatar
それだとタップ中のハイライト効果って自作できるの?
4:28 AM
なんか楕円で囲まれる凝った見た目じゃなかったっけ
Avatar
キャプチャしてrectで切り出しとかすればある程度再現できるかと
4:50 AM
delegateだとtouch downで発火してるので論外、見た目以前の問題ですね
4:52 AM
これ使えば指定範囲のキャプチャが得られるので、attributeの範囲からこれを作ればそれっぽくできると思う
Avatar
delegateでも長押しがあるから、発火はdown→upのupのタイミングじゃ?
Avatar
iOS13.1で破壊されましたね
Avatar
挙動変わったのかw
Avatar
iOS7以前の、scrollよりも優先されてた挙動に戻ってしまいました。
4:54 AM
当時はdelegateが使い物にならなかったので上記のworkaround使ってた記憶がある
Avatar
なるほど・・・
Avatar
あとはdelegateは空で実装して見た目だけ拝借するのもありかな
Avatar
スレ違いでしたらすみません! Xcode11.3を使っています。 基本的にStoryboard/xibでUIを構成しているのですが、 数字のみフォントをカスタムフォントにしたい のですが、何か方法ってありますでしょうか?? ご教示いただけますと幸いです。
Avatar
Kishikawa Katsumi 1/14/2020 8:22 AM
テキストの内容が固定で変わらないなら、UILabelやUITextViewにはAttributedStringを設定できるのでそれを使えばいいです。 Text => PlainとなってるところをAttributedを選択するとリッチテキストとして設定できるようになります。
Avatar
@Kishikawa Katsumi さん 返信ありがとうございます! 例えば、既存のUILabelで 現在2位 (過去41位) と表示している一つのラベルがあるとします。 このラベルの2, 41の部分だけAttributedStringでフォントを当てると いったことが可能と言う事でしょうか?
Avatar
Kishikawa Katsumi 1/15/2020 2:31 AM
できますよ。どこが分からないですか?
Avatar
AttributedStringでfontを指定する方法は分かるのですが 数字のみこのフォント とどうやって指定すれば良いのかわかっていないです!
Avatar
Kishikawa Katsumi 1/15/2020 2:44 AM
Interface Builderでやる方法ですよね? 例えばラベルならPlain => Attributedに変更して、そうするとリッチテキストが使えるので数字の部分だけ選択してフォントを変えたりできます。
Avatar
なるほど!! 実際にテキストを選択しながら適用していく訳ですね!! 選択しながらフォントが適用出来ると言う事を知りませんでした! ご丁寧にスクショまでしていただきありがとうございました! (edited)
Avatar
Kishikawa Katsumi 1/15/2020 7:25 AM
Storyboard(たぶんXIBでも)でUITextViewのTint Colorの指定が効かない、っていう問題がありそう。 (Xcode 11.3.1とiOS 13.3で確認) で、罠があって、 しょうがないからコードで指定するんですけど、その時Storyboardで指定した色とコードで指定した色が同じだとどっちも無視されるという結果になってハマる。
Avatar
omochimetaru 1/15/2020 7:25 AM
同じだとどっちも無視される
ひどいw
Avatar
Kishikawa Katsumi 1/15/2020 7:26 AM
(なんかコードでnilを入れてみたり、代入文を繰り返したりしてわかった)
7:26 AM
まっさらのプロジェクトでも再現したからあとでレポートしようと思う。
Avatar
omochimetaru 3/25/2020 3:40 AM
Constraints自体をつけ外しするとめっちゃ遅いというのはあった
3:40 AM
hogeConstraint.constantの調整で済ませないといかん。 (edited)
Avatar
それはするなって書いてある
3:40 AM
どこかに。
3:41 AM
どうしてもそうせざるをえない箇所もあるんだけど。
Avatar
omochimetaru 3/25/2020 3:41 AM
.multiplierlet なのでグギギってなったんすよね
Avatar
そうですねw
Avatar
omochimetaru 3/25/2020 3:41 AM
見直して作りを組み直したら解決したけど。 (edited)
Avatar
uiコンポーネントちゃんと作れる人じつはすごい少なくて
3:43 AM
レイアウトがどうやって解決されて動いてるのか知らないのにuikit使ってる人すごい多くてシニアレベルでもそうなので
3:43 AM
多分、仕組みを理解しないで使ってる人多いんだろうなあって。
3:44 AM
xibが悪いとは言わないけど
3:44 AM
簡単に見せようという努力と基本的に人間が怠惰なゆえに
3:44 AM
地獄がうまれてる気がしないでもない
3:45 AM
冷静に自分がレイアウトエンジンならどの情報が自分が知るべきことでどの情報は知っててはいけない=依存してはいけないとかわかるはずなんだけど。
3:45 AM
雑に作って動くってすごいことだけど
3:46 AM
8割いいけど2割ダメ程度までしかいけないよねえといつも思う。
Avatar
シンプルにたくさん壊してたくさん学んでくれたらそれでいいんですけど、破壊してることにあんまり気付いてもらえないのが結構厳しい
3:47 AM
AmbiguousなLayoutも無理くり動かすんじゃなくてちゃんと止まるモードとか用意してくれたら良かったのに、という気持ち。 (edited)
Avatar
素敵なことに、layoutengineは努力しちゃうからw
3:47 AM
「無理だけどいいようにしておきました」
Avatar
omochimetaru 3/25/2020 3:48 AM
AmbiguousなLayoutも無理くり動かすんじゃなくてちゃんと止まる
これは確かに。
Avatar
appleのコードでもでまくってるので
Avatar
omochimetaru 3/25/2020 3:48 AM
www
Avatar
それはそうなんだよな
Avatar
多分厳密にやったらけっこう大変なんだと思う
3:49 AM
サイズ0のときとかね
3:49 AM
ambigiousでいちばんあるあるじゃないかな
3:49 AM
constraitのconstantより小さい幅しかないときは
3:49 AM
どうしようもない
Avatar
ActivityViewControllerとか結構壊れがちだった気がする
Avatar
uinavigationbarがひどかった (edited)
Avatar
omochimetaru 3/25/2020 3:49 AM
完璧にするのが難しいから壊れててもなんか表示して動き続ける方を取ってるのか。
Avatar
一時期のSearchControllerも崩壊してましたよね。厳しさが高かった
Avatar
たぶん現実的にああいう動作に落ち着いたんだと思ってる
Avatar
omochimetaru 3/25/2020 3:50 AM
でもその結果壊れたまま学ばない人が出てきて治安がズブズブ悪くなると
Avatar
残念ながら...
Avatar
omochimetaru 3/25/2020 3:50 AM
悩ましいな
Avatar
手書きのレイアウトはどうしたって正しい理解が必要だし
3:51 AM
幅がたらないのに引き算したらマイナスになるしで
3:51 AM
まあ気付きやすい
Avatar
Frameはそうですね
3:51 AM
手書きのAutolayoutがかなり鬼門
Avatar
アニメーションはいるとレベルが10倍あがるけど。
Avatar
あっちこっち足りないとか余計なものがついてるとかは結構見てきた
Avatar
omochimetaru 3/25/2020 3:52 AM
ww
Avatar
自分はかなりパターン化してますね
Avatar
omochimetaru 3/25/2020 3:52 AM
UIStackViewとかは良い方向性なんじゃないすか?
Avatar
制約つける方角の順番とか
3:52 AM
UIStackViewは恐ろしくバグってた
Avatar
そう、なのでStackView使えお前ら、という方向性は、かなりいい塩梅でした。
Avatar
最近はいいかも。
Avatar
初期はやばかったですが、最近はかなりよい。
Avatar
omochimetaru 3/25/2020 3:53 AM
草。最初スルーしててちょうどよかった。
Avatar
11くらいまではやばかた記憶がる
3:53 AM
すげーデバッグした記憶あるし結論バグってことだったし。 (edited)
Avatar
omochimetaru 3/25/2020 3:53 AM
SwiftUIにAutoLayout載せないのかなあ
Avatar
幾つかワークアラウンド埋めると、10以降はまともに動いてましたね
Avatar
やらないと思うw
Avatar
10と11でremoveArrangedSubviewの動きに差異があるのは結構辛い
Avatar
omochimetaru 3/25/2020 3:54 AM
AutoLayoutをエンジンとしては敷いた上でStackViewみたいなパターンの道具を用意するってのが攻守最強な気がしているんだけどな
3:54 AM
SwiftUIはStackViewみたいなパターン「しかない」方向な感じに見える
Avatar
自前のそういうやつあるんですよ
3:55 AM
autolayoutベースじゃないんだけど
3:55 AM
layout metricっていう概念を導入して
3:55 AM
stack layoutみたいなのが縦方向と横方向にあって
3:56 AM
あとは計算したら全部キャッシュするみたいなそんなやつなんだけど
3:56 AM
APIがすごいむづい
3:56 AM
レイアウトって何回かやらないと解決しないパターンてのがあって
3:57 AM
だからimmutableじゃないオブジェクトとかいっぱい出てきて
3:57 AM
しかもあまり使われないパターンってのが結構バグってて
Avatar
omochimetaru 3/25/2020 3:57 AM
自前のってSwiftUIのですか?
Avatar
車輪の再発明感あるわーって思ってるんだけど
3:57 AM
それはUIKit。
Avatar
omochimetaru 3/25/2020 3:57 AM
ああ。
Avatar
それ以前のフルでマニュアルなやつはもうちょっと酷かったので
3:58 AM
ひどい同士で比べたらまだマシかなあー程度で、、、
3:59 AM
感じたのはどうしても8割OKみたいなものしかできないから
3:59 AM
どこかで
3:59 AM
誰かが頑張るのは必要で
4:00 AM
それがどれくらいシンドイものになるのかっていうのは評価方法としてありかなあと。
4:01 AM
SwiftUIがそういうのどれくらいのもになるのかあまり実戦投入してないからわからないけれど
4:01 AM
しばらくは移行とか雑に書かれたステート管理とかで
4:01 AM
罵り合いが起こりそうとは感じた
4:02 AM
マニュアルレイアウトはなにもないから単にちょっとタイプ数が多いってのがしんどいところかなあ。
4:03 AM
auto layoutは制約のプライオリティ管理がちょい大変
6:38 AM
protocolとclassで名前の付け方分けるべきなんだろうけどUIKitでこういうの付けられるとうーんって気持ちになる
Avatar
omochimetaru 6/25/2020 6:46 AM
空のクラスみたいな気持ちになればかぶっても良いのかなと思う
Avatar
なんかちょっとAPI的にアレ事実を発見したきがするんですが
5:37 AM
UIAccessibilityのNSObject拡張系propertyはSwiftからは操作できないっぽい...? (edited)
5:38 AM
isAccessibilityElement = false とか無視される (edited)
5:38 AM
accessibilityちゃんとやってるひと少ないと思うけれど
5:39 AM
これかなりアレな事実な気がする...
5:43 AM
いや、そんなことはないか流石に
Avatar
UITextView accessibility is unique. GitHub Gist: instantly share code, notes, and snippets.
6:50 AM
こう言うことだった
6:50 AM
Swift 微塵も関係なかった
Avatar
今更ですが、iOSDCの発表でアフィン変換についていろいろ調べてるけど、訳わからなくなったのでちょっと質問したいです まずアフィン変換を複数合成した変換をビューに適用すると、合成した順番とは逆の描画順番になるのが現状の動きです(図1) ちょっと変ですが、私は長い間ずっとこれUIKitの仕様だと思ってきました;そしてそうなってる理由は、恐らく行列の掛け算の順番を本来実行順の逆順にしないといけないところ(つまりA変換→B変換の順番なら、掛け算はB×Aの順番にしないといけない)、UIKitが実行順通りに掛け算(つまりA×B)をしてしまったと考えていました ところが、今実際ドキュメント読んでると、UIKitは確かにB×Aの順番で掛けてるようです;そして実際CGAffineTransformを出力してみても、確かにB×Aの順番の計算結果になっているのがわかりました。つまり、アフィン変換の計算自体は合っているはずです(図2) アフィン変換が合っているのに、描画が逆の順番の計算結果になっているってことは、つまり恐らく描画する時、CGAffineTransformのbとcを逆に使ってしまったバグになるのでは?と思いますが、皆さんはどう思いますでしょうか?
12:10 PM
Avatar
omochimetaru 9/8/2020 12:21 PM
変換を構成しているのではなくて
12:21 PM
座標系自体を変換しているので
12:22 PM
逆順に見えているのでは。
Avatar
これ線形代数でやった気がする
Avatar
omochimetaru 9/8/2020 12:25 PM
予想として書いてるのは、対象への変換を与えた結果です
Avatar
変換されるのは図形ではなく軸なので〜だったかな
Avatar
omochimetaru 9/8/2020 12:25 PM
実際の結果は、座標系の変換された結果です
Avatar
大学時代に線形代数とCGの授業で、一般に逆順になる、というような内容をやったのがあやふやな記憶の中にある
Avatar
omochimetaru 9/8/2020 12:25 PM
そうそう。予想のところの図にかいてある、二本の矢印を、変換してる。 (edited)
12:25 PM
緑の四角形ではなくて。
Avatar
Affine変換のときに歪んでるのはモノではなく世界なんですよ
Avatar
omochimetaru 9/8/2020 12:26 PM
いや、それはAPIの組み方次第だから
12:26 PM
どっちと捉えても良い
Avatar
確かにそれはそうか
Avatar
omochimetaru 9/8/2020 12:26 PM
受け止め方と仕様の問題で、アフィン変換自体は数式的には同じ
12:27 PM
メソッドチェーンしたときに新しい変換が数式の右に付け足されてるのか左に付け足されてるのかが、ライブラリによって異なる
Avatar
大学時代に線形代数とCGの授業で、一般に逆順になる、というような内容をやったのがあやふやな記憶の中にある
言いたいのは、私もCGAffineTransformの計算が「正順」になったのでは?と思っていたところ、確かに計算自体は「逆順」で間違いなかったことです ところが、実際の座標計算(xとyの値)は、「正順」で計算したときの値になってしまうことです
12:29 PM
要するに、書き方も、実際の計算も、A変換→B変換(B変換×A変換)のはずだが、表現されてる座標がA変換×B変換の結果になってることです
Avatar
omochimetaru 9/8/2020 12:30 PM
abcdの並びは
12:31 PM
列ベクトルに合わせたレイアウトになっているので
12:31 PM
行ベクトルで考えているなら転置して捉える必要がありますよ
12:32 PM
たしか a b 0 c d 0 x y 1 こうだったような。
Avatar
列ベクトルで計算してるはずです 🤔 そもそも行ベクトルなら、Affine×座標ではなく、座標×Affineしか成立しないので
12:33 PM
a b tx x c d ty × y 0 0 1 1 ですね
Avatar
omochimetaru 9/8/2020 12:33 PM
あー
12:34 PM
間違えた、えっと、普通と違って行ベクトルだと言いたかった
Avatar
!?
Avatar
omochimetaru 9/8/2020 12:35 PM
行ベクトルだと思ってるのか、単にストレージが転置してあるのかは
12:35 PM
どっちなのか理解してないんですけど
12:35 PM
とにかく、 a b tx c d ty 0 0 1 だと思ってると間違うんですよ。
12:36 PM
なんかドキュメントがあるはず (edited)
12:36 PM
12:37 PM
あった。これです。
Avatar
ファっ!? そしたら掛け算順番逆にした意味ないじゃん!?
12:39 PM
↑このツリーに以前整理した話がある
Avatar
何故CGAffineTransformはbとc逆にするし 😇
12:41 PM
ありがとうございます!
Avatar
omochimetaru 9/8/2020 12:43 PM
このレイアウトは一見気持ち悪いんですが
12:43 PM
行列がベクトルの配列だと思ったときに
12:44 PM
行ベクトルの配列と、行列が、同じメモリレイアウトになるんですよね
12:45 PM
逆に、列ベクトルを基準に構成してしまうと、 行列は列ベクトルの配列にならない。 一列目を取り出すとm[0] m[4] m[8] m[12]になってしまう。
12:45 PM
そのあたりが理由なのかなあと想像してます
Avatar
メモリレイアウトの都合でそうするのは別に構わないですが、それならそれで掛け算の順番を逆にするなよと思います正直…それ列ベクトルで計算するときの掛け算順番じゃん
Avatar
omochimetaru 9/8/2020 12:49 PM
ややこしいですよね 触るたびにまずその辺の確認からやってる
Avatar
英語の言葉の順番のせいかなっと、とりあえず勝手に片付ける 確かに英語で「Aed-Bed」の言葉なら、順番としては先にBされてからAされるって言うイメージ 🙄
Avatar
このあたり、概念的に行ベクトル前提か列ベクトル前提か、メモリレイアウトが行メジャーか列メジャーか、メソッドが左からかけてるか右からかけてるかあたりの組み合わせで反転しまくるからややこしい。
Avatar
omochimetaru 9/8/2020 1:26 PM
概念の反転と実装の反転の2つがあるのヤバいんだよなあ (edited)
Avatar
たしか、 SCNMatrix, GLKMatrix, simd_double が全部違ったような気がする。 (edited)
1:27 PM
概念の反転と実装の反転の2つがあるのヤバいんだよなあ
そう、これで見かけ上戻ったりするんよね。違うものなのに。
1:27 PM
Ray さんが昔 iOSDC でこのあたりの混乱を上手く扱うための方法を話してたはず。
1:28 PM
↑これだ。
Avatar
omochimetaru 9/8/2020 1:30 PM
懐かしい。これ見てから結構 XXXFromYYY ってリネーム採用してる。
1:30 PM
XXXToYYYも使うけど・・・
Avatar
これの前から xxxToYyy にしてて、ネイティブは from なのかぁと思った。
1:32 PM
↓こういう .transform とかも、どっちからどっちへの変換なのかを名前で表してくれないと、いつも混乱する。 https://developer.apple.com/documentation/scenekit/scnnode/1407964-transform
1:33 PM
メソッドも掛け算の左右がはっきりしないから * で書きたくなる・・・。
Avatar
omochimetaru 9/8/2020 1:33 PM
* 演算子に限っては
1:33 PM
A * B って書いたら Aが左でBが右になるやつしか見たこと無い
Avatar
うん。 * だけは信頼できる。
1:34 PM
さすがにそこひっくり返ったらヤバいw
Avatar
omochimetaru 9/8/2020 1:34 PM
まあねw
Avatar
数学だけは全人類に共通する言語()
🤔 1
Avatar
記法の違いさえ乗り越えたら数学は全宇宙で通用するでしょうね。物理学と化学もだけど。多分基礎的なアルゴリズムとかも(数学の一種ですが)。
2:03 PM
カール・セーガンの『コンタクト』の中で、言葉の通じない宇宙人とどうやってコミュニケーションするかということが論じられていておもしろかったです。まずは論理とか数学とか共通概念から伝えるんだけど、どうやってたっけな・・・。手元に本はあるけど紙の書籍だから当該ページを簡単に見つけられない・・・。 (edited)
Avatar
皆さんのおかげで昨日無事iOSDCの収録が完了しました、ありがとうございます 🙇‍♂️
rtaGg 1
Avatar
girigiri?
kusa 2
Avatar
good game
Avatar
超ギリギリでした、21:30の枠で収録完了でしたwww
Avatar
セットアップすごい大変だった
12:45 AM
Keynote をプレゼンタースクリーンを出しながら 16:9で出すのが至難の技
12:46 AM
最終的にHDMIのダミーheadlessプラグをつかって16:9の画面をつないでそこに出力という手法にたどり着いた
Avatar
自分も同じく、デュアルモニターですが外付けは21:9のアスペクト比なので、少しでも16:9に近づけようと最初MacBook自身の16:10でやってみましたが、プレゼンタースクリーンがいつもと逆のモニターですっごい見辛くてめっちゃくちゃ滑りましたw 最終的には結局いつもの方法でOBSで合成した出力をバーチャルカメラとしてZoomに流しましたw
Avatar
あー、virtual camera出力をscreen sharingのソースで使えるんだっけ
Avatar
はい、第二のカメラソースとして流せばOKですー
Avatar
それが正解っぽいなあ
12:55 AM
できないと思って試さなかった。
12:55 AM
いつもOBS間に入れられれば勝てる気がする
Avatar
ただ私の場合、そもそも画面共有だけでなく通常のビデオソースでも、本物のカメラを封印してOBSのやつを流してるので、本人と画面共有が同じものになっちゃいますw
Avatar
本人が画面w
Avatar
在宅勤務だと制服がパジャマ()
Avatar
突然ですが、詰まってしまったので質問させてください
8:28 AM
Storyboard上のUIImageViewなどのimageに別Bundle内のアセットを割り当てることは可能でしょうか?
Avatar
Storyboard上でBundle指定するUIがあれば可能で、なければ出来ないのでコードから差し込みます
Avatar
omochimetaru 11/2/2020 8:29 AM
https://developer.apple.com/documentation/uikit/uiimage/1624154-init コードからはこれでできるけどStoryboard上はできないんじゃないかしら
Avatar
ViewやViewControllerはバンドル指定ができた記憶がある。画像はわからない
Avatar
omochimetaru 11/2/2020 8:30 AM
UIがあれば可能で
そうですね。あればできる。記憶にはないけど
Avatar
プロジェクトのEmbedded Framework化を進めていて、リソースをすべて集めたバンドルを作り、アセットをバンドルにまとめて、共通UIやFeatureモジュールで参照しようとしていますが、 Could not load the "image" image referenced from a nib in the bundle with identifier "Bundle ID". のエラーが出てしまいます。 書くFrameworkにAssetをコピーすると解決できますが、ビルド成果物にアセットが重複してしまい、サイズが大きくなってしまうという状況です
8:32 AM
やはりコードになるんですかね.... prepareForInterfaceBuilderで挿し込むことも考えましたが、Storyboardの量が多く、躊躇してしまっています
Avatar
omochimetaru 11/2/2020 8:36 AM
XIBから参照されるバンドルは、そのXIB自体が入っているバンドルなので
8:36 AM
storyboardファイルをその画像が入っているバンドルに入れたら、
8:36 AM
読み込めたと思います。
8:37 AM
リソースをすべて集めたバンドルを作り
このバンドルにstoryboardもリソースとして入れてしまうとか。
8:37 AM
画面(機能)グループでバンドルを分けたくて、でも共通素材は別のバンドルにまとめたいなら、コードしかない気がします。
Avatar
なるほど 各ViewControllerより下位のレイヤーにViewControllerのStoryboardと画像を含んだFrameworkを作って、instantiateした実体をDIする感じになりそうですね
8:40 AM
ありがとうございました 🙇‍♂️ もう少し検討してみます
🙂 1
Avatar
タブにタイトルを表示せずにアイコンだけ表示しているアプリって多いですが、 UITabBarController を使うならタイトルを消すのは推奨されないと思っているんですがいかがでしょうか?
Avatar
基本的にラベルなしのボタンってわかりにくい上に、結構何なのか解らないボタン多くて「あああああ」ってなりますね まあでもタブなら数回押せば覚えるし破壊的変更を加えないので、そこまで大きな問題でも無いかなとは思います。デザイナーの腕次第っぽい。 (edited)
Avatar
UX的な話もありますが、 UITabBarController 的に良くないんじゃないかと。
Avatar
それでいうとハック噛ませるとAccessibilityとか結構死ぬはずで、良くないことのは間違い無いですね (edited)
Avatar
タブにタイトルを表示せずにアイコンだけ表示しているアプリって多いですが、 UITabBarController を使うならタイトルを消すのは推奨されないと思っているんですがいかがでしょうか?
ウッ頭が
Avatar
よくある edge insets で調整する系のやつ、 OS バージョンアップで壊れない保証がない気がします。
Avatar
むむっ
11:11 PM
ま、壊れたら直せばいいし感ある
Avatar
継続メンテ前提のアプリなら直せばいいのはそうですね。
Avatar
UIKitで壊れない理由はなさそうだよなあ
11:13 PM
実数指定がある以上は、どうしても何処かで。
Avatar
めっちゃ実用的なハックをStack Overflowで見つけてしまった。 UIActivityControllerのsubviewを全部剥がすと、ハーフモーダルの機能だけが残るので、Subview貼ると簡単にハーフモーダル作れる。 https://stackoverflow.com/questions/57712766/recreate-ios-13-share-sheet-modal-in-swift-not-the-share-sheet-itself-but-the
is there a way to easily recreate the modal presentation style of ios 13' new share sheet? (At first, it's only presented halfway and you can swipe up to make it a "full" modal sheet) I can do it u...
👀 1
Avatar
www 内蔵くり抜いて皮だけ使うのか
Avatar
Kishikawa Katsumi 12/15/2020 9:39 AM
これはいい
Avatar
この皮有用なので一般公開してほしいんだがなぁ
Avatar
Kishikawa Katsumi 12/15/2020 9:40 AM
昔UIImagePickerViewControllerからサブビューを外してカメラのUIをカスタマイズしていたのに通じるものがあるな。
Avatar
↑これ使ってたんですが、 iOS 13 のときは動いてたのに iOS 14 でうまく動かなくなって、やっぱりいつ壊れるかわからなくて危険だなと思ってやめました。ただ、原因がどこにあるかまでは調べてなくて、 SwiftUI 経由で使ってたので他のところに原因があるかもしれません。
Avatar
今のところUIKitで使っている分にはiOS 14でちゃんと動いてそう
👍 1
Avatar
これ追加情報で、removeFromSuperviewすると何かしら裏でアクセスが走った時にbad accessになるので、isHiddenにすると今のところ大丈夫
Avatar
Kishikawa Katsumi 12/20/2020 3:28 PM
なるほど?確かにAppleの実装がIBOutletをWeakで保持している場合なんかはそういうこと起こりそう。
Avatar
isHidden切り替えられると死ぬのでalphaも0にしておこう
Avatar
iPadOSで、任意の座標をタッチさせる機能は存在しますか? 相対的に移動させるのであればマウスでできるんですが、任意の場所へタッチすることが必要であり、マウスデバイスとしてのアクセスはあきらめました。 その代わりにタッチ機能で代替できるのではないかと考えています。 以前同様の内容で質問した時に、Private APIでアクセスすればあるかもしれないという話でしたが、マウスの移動関係のAPIはどこを探せばあるかわかりますか?
Avatar
https://developer.apple.com/documentation/uikit/pointer_interactions この辺から探していくんだと思いますが、肌勘ですがお探しのものは無いんじゃないかなとは思います
Avatar
Avatar
tarunon
https://developer.apple.com/documentation/uikit/pointer_interactions この辺から探していくんだと思いますが、肌勘ですがお探しのものは無いんじゃないかなとは思います
今結構調べてるんですが、基本的にはできない前提で調べてます!
Avatar
webだとclickevent作ってfireとか出来るんですが、今って多分そういうのは非推奨の流れで
9:25 AM
UIKitは若いので無い可能性が高いかな〜と
Avatar
Avatar
tarunon
webだとclickevent作ってfireとか出来るんですが、今って多分そういうのは非推奨の流れで
webだと確かにあるみたいですが、ターゲットは限定していません。 調べた限りかなり難しそうです:(
Avatar
https://developer.apple.com/documentation/uikit/uiapplication/1623043-sendevent UIApplication.sendEventにUITouchEvent流し込んだらいけるんかねえ?
Avatar
Avatar
omochimetaru
https://developer.apple.com/documentation/uikit/uiapplication/1623043-sendevent UIApplication.sendEventにUITouchEvent流し込んだらいけるんかねえ?
今、UITouchイベントをこちら側で生成してsendEventを実行しようとしています。 問題としては、UITouchが保持する座標(location関数で取得可能)を変更可能かということです。 単純にアクセスできない(UITouch.xのような感じ)のですが、変更する方法はありますか?
Avatar
@dangomushi.3 ああそうか、それができないですね。 一応 UITouch を継承したサブクラスを作って、 location関数の実装をオーバーライドすれば動くかもしれないけど、その方針は厳しそうです。
Avatar
ちなみに、UITouchを直接sendEventできないのですが、キャスト等すればUIEventとして扱えるようになるのでしょうか?
Avatar
UIEventがUITouchを持つという構造なので、
5:22 AM
作るのはUIEventですね
Avatar
UIEventを作成するときに、以下のことはできますか?(試してみましたができなかったです) ・イベントタイプをタッチにする (edited)
Avatar
Avatar
dangomushi.3
UIEventを作成するときに、以下のことはできますか?(試してみましたができなかったです) ・イベントタイプをタッチにする (edited)
継承してサブクラスを作ってeventTypeプロパティをオーバライドするとできると思います。
Avatar
Avatar
omochimetaru
継承してサブクラスを作ってeventTypeプロパティをオーバライドするとできると思います。
オーバーライドでできました! あとはlocationさえ設定できれば行けそうなんですけど、それがとても難しそうです。。。
Avatar
Avatar
dangomushi.3
オーバーライドでできました! あとはlocationさえ設定できれば行けそうなんですけど、それがとても難しそうです。。。
locationもオーバライドですね。 座標値の計算はこれ使うと良いです。 https://developer.apple.com/documentation/uikit/uiview/1622442-convert
6:11 AM
あと、UITouchは、継続してトラッキングして同じ指だと判定されているタッチは同じインスタンスを使うという仕様があるので、そこが実装上注意が必要かも。
6:12 AM
毎フレーム新しいUITouchオブジェクトを作ってはだめ。
Avatar
座標変えるのもRunloopに処理を返しながら都度変更とかやらないといけないかな
Avatar
Avatar
omochimetaru
locationもオーバライドですね。 座標値の計算はこれ使うと良いです。 https://developer.apple.com/documentation/uikit/uiview/1622442-convert
locationは関数として設定されていますが、自分で設定するにはどんな感じでオーバーライドすればいいと思いますか? 以下のようにpropertyがある前提でオーバーライドしようとするとエラーが出ました var touchedLocation: CGPoint override var location: CGPoint{ get{ return touchedLocation } set(p){ touchedLocation = p } } たくさん質問に答えていただきありがとうございます (edited)
Avatar
override func で関数としてオーバライドしましょう
Avatar
Avatar
omochimetaru
override func で関数としてオーバライドしましょう
試してみます!結果が分かり次第れんらくさせてもらいます!
Avatar
Avatar
omochimetaru
override func で関数としてオーバライドしましょう
location関数はUITouchで宣言されており、継承しているのはUIEventでlocation関数は定義されていないんですが、 こういう場合はどのようにオーバーライドするべきでしょうか
Avatar
UITouchもサブクラスを作ります
Avatar
Avatar
omochimetaru
UITouchもサブクラスを作ります
UIEventとUITouchイベントそれぞれで作ったサブクラスを一つのUIEventクラスとして統合することはできますか?
Avatar
継承したサブクラスをMyEventとMyTouchだとして、
6:44 AM
MyEventのtouchesメソッドでMyTouchを返します
Avatar
https://developer.apple.com/documentation/uikit/uievent をみながら以下のようにoverrideしてみたんですが、Method does not override any ... というエラーが出ます var touch: MyTouch override func touches(for: UIView) -> Set<MyTouch>{ return [touch] }
Avatar
返り値の型は Set<UITouch>? にします。
Avatar
なるほど!エラーが消えました! とりあえずこれでテストできそうなので実装してみます!
Avatar
あとはsendEventを利用する必要があるのですが、どのようにして呼び出せばいいでしょうか。 いまはContentViewのなかでイベントの調整をかいているのですが、その内部からsendEventが呼び出せないです
Avatar
UIApplication.shared.sendEvent を呼べば良いです (edited)
Avatar
呼び出しできました! MyTouchおよびMyEventからイベントを投げることころまではもうエラーは出なくなりました! ただ、まだマウスポインタが指定場所へ移動できていないので調整してみます! UITouchイベントを投げるだけではマウスポインタの座標はかえられないのかもしれないですね
Avatar
マウスポインタは動かせないと思います
7:40 AM
マウスポインタの制御の結果、UIApplicationにUIEventが届くのであって
7:40 AM
UIApplicationに届いたUIEventによってマウスポインタが処理されているわけではないです、順番が逆
7:41 AM
ただ、ボタンとかに対して、タップイベントを送れば、ボタンのタッチ処理を起動させたりはできるかもしれない、と思って書いてました。
Avatar
やはりそうですよね 結果としてのイベントであって、それを送ることで操作できるわけではないですよね 技術的にはやはりむずかしいですかね?
Avatar
難しいというかAppleが方法を提供してないので無理だと思います
Avatar
すごいクリスマスプレゼントが投下された https://twitter.com/pducks32/status/1341877266490355712?s=21
Merry Christmas! 🎄We just released 3 really detailed talks on UI performance in your apps on ’s OSes. Think iOS 14 was smooth? Come see how and learn tips to keep your app at framerate. First I explain how the render loop works and what is a “hitch.” https://t.co/t6DROBBE3k
Likes
239
Avatar
Kishikawa Katsumi 12/24/2020 12:10 AM
これはいいね。冬休みなくなりそう。
Avatar
View Hierarchy エクスポートできるようになっててフィードバック送るのに便利
Avatar
iPad 120Hzだったのか
Avatar
こんにちは。UICollectionViewCompositionalLayoutについて質問があります。NSCollectionLayoutSectionorthogonalScrollingBehavior.none 以外にすると、NSCollectionLayoutSupplementaryItem の表示順序が狂ってしまうのですが、どなたかこの現象に出くわしたことはありませんか?常に最前面に表示したいのですが、もしご存じでしたら実装方法について教えていただけると幸いです。
5:39 PM
例えば、.noneの時はバッジが常に最前面に表示されているのですが、
5:40 PM
.continuousだと、このようにバッジがセルの後ろに移動してしまう場合があります。
5:43 PM
ハイライトした行を追加すると再現します。ちなみに、サンプルとは別のコードですが、.none以外を指定することでiOS13, 14ともにシミュレータで再現しました。 (edited)
6:09 PM
.none はデフォルト?
6:09 PM
ああ、.none "以外" か
6:10 PM
UIKitのバグっぽいなあ
🙏 1
Avatar
Avatar
niw
UIKitのバグっぽいなあ
ですよねぇ...13, 14両方とも後ろに回ってしまうので正常?な挙動かと思ってたんですが、zIndexを変更しても状況は変わらず...cellに直に乗せてしのごうと思います😫 (edited)
Avatar
バッジビューのlayer.zPositionで回避できませんか? ↑のサンプル(iOS14)では最前面になりました
💯 1
👍 1
❤️ 1
Avatar
Avatar
nanasi
バッジビューのlayer.zPositionで回避できませんか? ↑のサンプル(iOS14)では最前面になりました
おお!回避できました、ありがとうございます!!たしかにsubviewとしてcellに登録されているのでworkaroundとして機能するのですね。layer.zPosition で無理矢理前に持ってくるのは盲点でした、、(zIndex とは...)
Avatar
Miwa / Ensan 6/4/2021 7:40 AM
こんにちは、キーボードの制御について質問があります。アプリ内でサードパーティ製のキーボードを開くことを強制する方法はありますか?ご存知の方がいらっしゃったら教えていただきたいです。
Avatar
Kishikawa Katsumi 6/4/2021 9:50 AM
逆は可能なんですけどカスタムキーボードを使う、というのはないですね。 もし自分が作っているキーボードで同じUIが出せればいいというのであれば、inputViewに設定すればできます。 (ハードウェアキーボードが繋がってるときを除く)
Avatar
Miwa / Ensan 6/4/2021 9:52 AM
私もその理解だったんですが、別のアプリで類似の挙動を見つけて気になっています。
Avatar
Kishikawa Katsumi 6/4/2021 9:54 AM
お、それは興味深いですね。
Avatar
Miwa / Ensan 6/4/2021 9:54 AM
Simejiのアプリ内では事前に何を設定していても必ずSimejiが開かれる(ユーザ側で指定し直すことはできる)ので、どうなっているのかな、と
Avatar
Kishikawa Katsumi 6/4/2021 9:55 AM
Simejiアプリが出してるのが実はinputViewに設定したビューっていうのがありそうですけど、 きっとキーボードの切り替えボタンが表示されているんですね?
Avatar
Miwa / Ensan 6/4/2021 9:57 AM
❗ 1
9:57 AM
アプリ内でも同様ですが、アプリ外でも設定が変わりますね
9:58 AM
他のキーボードアプリではそういうことはないので、iOS側が制御しているということはなさそうなのですが……
9:59 AM
Simejiの場合は切り替えボタンが独自実装されているので、アプリ内だけならinputView方式で説明がつきます
Avatar
Kishikawa Katsumi 6/4/2021 10:00 AM
なるほど。そういう挙動なんですね。確かにSimejiアプリを経由するとSimejiのキーボードに変わりますね。
10:05 AM
UITextInputDelegate のプライベートメソッドに setInputMode: というのがあるので、UITextInputDelegate のオブジェクトを捕まえて値をセットしたら変わったりするんだったかな。。。?のような非公式の方法しかないんじゃないかなあ。。。
Avatar
Miwa / Ensan 6/4/2021 10:54 AM
UIInputViewController(UITextInputDelegateに準拠)はその関数を持っていないように見えます
Avatar
Kishikawa Katsumi 6/4/2021 11:03 AM
Simejiアプリを経由すると切り替わるってことはSimejiアプリが何かそういうキーボード切り替えのような呼び出しをやってるのかなと思ったんですよね。
Avatar
Miwa / Ensan 6/4/2021 11:49 AM
そうですね、おそらくアプリが開かれたタイミングで何かしら制御していそうです
Avatar
textInputMode のことかな
Avatar
Kishikawa Katsumi 6/4/2021 3:20 PM
あれ、もしかして適当なビューでtextInputModeを返したら狙ってキーボードを出せるのかな?
Avatar
Miwa / Ensan 6/4/2021 3:30 PM
Solution Here is a full solution/work around for this issue, please up vote Blld's answer as well because this was the vital bit of info needed! Alternative titles to aid search Showing the Emoji
Avatar
A standalone, flexible API that provides a full-featured rich text editor for iOS applications. - twitter/TwitterTextEditor
3:31 PM
これですね
3:32 PM
なお iOS13 ではバグってるので注意 (edited)
3:34 PM
この実装は、emoji キーボードとか出すように作ってあるけど、まあ似たような感じでやればなんかできると思う、3rd party キーボードを出すってのを試したことはないけど。
3:35 PM
その stackoverflow のはバグワークアラウンドは何も考えて実装されてないので真似しちゃダメ
3:35 PM
というか stackoverflow は基本無視 (というか検証が絶対必要) (edited)
👀 1
Avatar
Miwa / Ensan 6/4/2021 3:38 PM
なるほど、ありがとうございます
3:38 PM
試してみます
👍 1
Avatar
Miwa / Ensan 6/4/2021 4:00 PM
iOS14で試した限り、システムキーボードに対してはこの方法で動作し、サードパーティ製のものを返した場合は動作しませんでした
Avatar
えー、まじかー。
4:28 PM
そこに違いはないと思うんだけどな...
🧐 1
Avatar
iOSの Picture in Picture のプレーヤーって、ホーム画面のDockや純正タブバー、TwitterのツイートFAB等々をよしなに避けてくれると思うんですが、自分のViewを避けて欲しい時ってどうすれば避けてくれるんでしょうか?TwitterアプリがツイートFABを避けさせてる以上何かしらの方法はあるんじゃないかと思っているのですが見つからず… (edited)
Avatar
多分SafeAreaに反応してるんですよねアレ
Avatar
Kishikawa Katsumi 6/13/2021 12:29 PM
Safeareaだと思う。additional safeareaとか設定したらいいんじゃないかな。
Avatar
確かに additionalSafeAreaInsets で制御できました、ありがとうございます!
Avatar
Kishikawa Katsumi 6/13/2021 11:52 PM
PinPでいろいろアプリを見るとタブバーを避けるかどうかで標準のかどうかある程度わかるね。
👀 2
Avatar
https://twitter.com/k_katsumi/status/1668167762420826115?s=61&t=iFqmsD7cRU2VGBfXFx0YxA @Kishikawa Katsumi ちょっと試して思ったんですけど、同じNavigationControllerに乗せちゃうと遷移前と後のNavigationBarは同じなので設定変えるの出来なかったりしませんか?
@noppefoxwolf 前後の画面でNavigationBarの設定が違うとそうなる、って感じですね。Twitterで詳しく説明するのは文字数が足りないんですけど。
Avatar
Kishikawa Katsumi 6/12/2023 8:30 AM
や、前と後ろで設定が違うと(色が違うとか)アニメーションが勝手に変わるんですよ。 (edited)
👀 1
Avatar
いろいろ試していているのですが条件厳しそうですね…全然再現しませんでしたw SO見てるとnavigationBarのhiddenで遷移前後変えるとスタックアニメーションするみたいなのもあったので、もしかするとiOS16ではオミットされてるかもしれないですね
Avatar
Kishikawa Katsumi 6/12/2023 7:38 PM
なんと。今度ワタシも調べてみる。
Avatar
navigation bar はその位置によって挙動が変わる...
👀 1
Avatar
Kishikawa Katsumi 6/12/2023 11:08 PM
ちなみにそういう表現にしたい理由は下のビューのサイズが決まったときにガクッとなるのを避けたいってことですか?
Avatar
NavigationBarのサイズを画面ごとに変えたいのですが、普通にやると高さのイージングが効いてしまって伸ばした部分が埋まりながら次の画面に遷移しちゃうんですよね
Avatar
NavigationBarは触るべきじゃないですね・・・
Avatar
実装が魔境なんだよなあ。。
Avatar
その通りだとは思ってて、現状NavigationBarを隠して自前のやつを乗せてるんですけどカスタムじゃないNavigationBarの画面を行き来するときに、画面遷移のたびにsetNavigationBarHiddenするのも結構あれな感じがしてるんですよね
3:01 AM
あと自前NavigationbarだとscrollEdgeAppearanceが再現できない、、 (edited)
Avatar
カスタムする場合はカスタムを貫くべきで、カスタムじゃないNavigationBarを持った画面をpushしない方針にするのはどうでしょうか
Avatar
なんか auto layout で謎のビューを追加して挙動を矯正するみたいなやばいハックをいろいろやってた記憶がある
🤮 1
Avatar
カスタムする場合はカスタムを貫くべきで、カスタムじゃないNavigationBarを持った画面をpushしない方針にするのはどうでしょうか
選択肢としてはアリなんですけど、アクセシビリティとか標準挙動とかを諸々考え出すとなるべくデフォルトのUIが使いたいなぁと。じゃあカスタムするなよって話ではあるんですけどw
3:04 AM
iOSのカレンダーアプリとかNavigationカスタムしてるのにかなり綺麗な動きしてるんですよね
Avatar
そこはもうトレードオフなんで、デザイン側でカスタムしないようにしてもらうしか・・・
👈🏻 3
🐱 1
Avatar
CatalystとかMacの挙動を考えるとカスタムしないのが一番ではあるんだろうなぁ…
Avatar
Kishikawa Katsumi 6/15/2023 4:14 AM
iOSのカレンダーアプリはうまいことつじつまがあってるからだな。 カレンダーアプリのようにナビゲーションバーの有り無し(透過の有無)が交互になるようにするとうまくいく。
Avatar
あとカレンダーは遷移後のnavigationbarのshadow消してるんですね。これのおかげでnavigationbarの高さが変わっても違和感がない。 曜日の部分がviewcontrollerの移動量と違うのも貢献してそうだけど、こっちは公開されてるAPIがなさそうですね
Avatar
質問: UINavigationController の遷移アニメーション時、前後のVC同士が被らないように変更することは可能なんでしょうか? 背景: 現在 Share Extension で脱 SLComposeServiceViewController をしていて (理由としては、なんか iOS 13 あたりから背景に対して中身が小さくなって不恰好なことや、マルチアカウントを強く意識したアプリなので最初にユーザーにアカウントを選ばせたい、アプリ側の投稿画面とボタンの位置等を統一したいなどがあります)、ただし見た目はなるべく元のままにしたい (のとすりガラスが好き) ので、背景に UIVisualEffectView + UIBlurEffect を敷いてみています。 ところが、
  • UINavigationController (のサブクラス)のviewで UIVisualEffectView を背景にして、各子VCの背景は透明にすると、画面遷移中に遷移先VCの裏に遷移元VCがまるまる見えてしまう
  • 各子VCの背景に UIVisualEffectView を敷くと、それはそれで画面遷移中に一瞬 UIVisualEffectView が二重になり微妙な感じになる ということがわかりました。 では SLComposeServiceViewController はどうやっているのだろう?と観察すると、どうやら UIPageViewController のように遷移元VCと遷移先VCが隣にいる状態でスライドするだけ (重なりはしない) なので違和感がない、ということに気づきました。 これを UINavigationController で再現することは可能なのでしょうか?それとも自前で実装するしかないのでしょうか?
(edited)
Avatar
Kishikawa Katsumi 8/1/2023 7:45 PM
UINavigationControllerでそういうアニメーションはないと思います。ただ遷移アニメーションをカスタマイズするのはTransitionDelegateを使って割と簡単にできるのでTransitionDelegateを設定して、スライドインしてくるようなアニメーションを前後の画面に対して設定するとできると思います。
👀 1
Avatar
Kishikawa Katsumi 8/1/2023 10:12 PM
サンプルを探してみたけどあまりなかった。 https://github.com/cjwirth/NavigationControllerTransitions ^ は古いけどSwift 4を指定してXcodeの言うとおりにコンパイルエラーをFixitしていったら動いたから試すのは簡単だと思う。横にスライドじゃなくて縦にモーダルビューのようにアニメーションするんだけどそれをアニメーションを変えるだけだから問題ないと思う。 さらにSwipe Backに対応するにはUIViewControllerInteractiveTransitioningとUIPercentDrivenInteractiveTransitionを使ったりします。
Sample project showing how to retain the swipe back function on UINavigationControllers when using custom transitions - GitHub - cjwirth/NavigationControllerTransitions: Sample project showing how ...
Avatar
スワイプの実装加えたいなどを含めて考えると、UIPageViewControllerで実装する方が近道なように見えてますが、どうでしょうか
Exported 1,247 message(s)
Timezone: UTC+0